Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What happens if undefined C++ behaviour meets C defined behaviour?

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?

like image 832
Daniel Stephens Avatar asked Oct 05 '19 16:10

Daniel Stephens


People also ask

What are the consequences of undefined behavior?

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.

Why does C have so much undefined behavior?

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.

Is unspecified behavior 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.

What does undefined behavior mean in C?

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.


1 Answers

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.

like image 97
S.S. Anne Avatar answered Nov 15 '22 18:11

S.S. Anne