I have a *.cpp
file that I compile with C++ (not a C compiler). The containing function relies on a cast (see last line) which seems to be defined in C (please correct if I am wrong!), but not in C++ for this special type.
[...] C++ code [...]
struct sockaddr_in sa = {0};
int sockfd = ...;
sa.sin_family = AF_INET;
sa.sin_port = htons(port);
bind(sockfd, (struct sockaddr *)&sa, sizeof sa);
[...] C++ code [...]
Since I compile this in a C++ file, is this now defined or undefined behaviour? Or would I need to move this into a *.c
file, to make it defined behaviour?
Undefined behavior can result in a program crash or even in failures that are harder to detect and make the program look like it is working normally, such as silent loss of data and production of incorrect results.
It exists because of the syntax rules of C where a variable can be declared without init value. Some compilers assign 0 to such variables and some just assign a mem pointer to the variable and leave just like that. if program does not initialize these variables it leads to undefined behavior.
Unspecified behavior is different from undefined behavior. The latter is typically a result of an erroneous program construct or data, and no requirements are placed on the translation or execution of such constructs.
When we run a code, sometimes we see absurd results instead of expected output. So, in C/C++ programming, undefined behavior means when the program fails to compile, or it may execute incorrectly, either crashes or generates incorrect results, or when it may fortuitously do exactly what the programmer intended.
This is defined in both C++ and C. It does not violate strict aliasing regulations as it does not dereference the resulting pointer.
Here's the quote from C++ (thanks to @interjay and @VTT) that allows this:
An object pointer can be explicitly converted to an object pointer of a different type.
Here's the quote from C (thanks @StoryTeller) that allows this:
A pointer to an object type may be converted to a pointer to a different object type.
These specify that one pointer type can be converted to another pointer type (and then optionally converted back) without consequence.
And here's the quote from POSIX that allows this specific case:
The sockaddr_in structure is used to store addresses for the Internet address family. Pointers to this type shall be cast by applications to struct sockaddr * for use with socket functions.
As this function (bind
) is part of the C standard library, whatever goes on inside (specifically, dereferencing the type-casted pointer) does not have undefined behavior.
To answer the more general question:
C and C++ are two different languages. If something is defined in C but not in C++, it's defined in C but not in C++. No implied compatibility between the two languages will change that. If you want to use code that is well-defined in C but is undefined in C++, you'll have to use a C compiler to compile that code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With