No, there's no undefined behaviour in this case. Undefined behaviour means the compiler makers are free of doing whatever they want with the affected resources. This means you are free (in this context) to define new non clashing underscored identifiers to be accepted in the two languages the compiler is able to implement. Think that the internals of the standard libraries implementations of compiler libraries can be full of such undefined behaviours as far as the compiler behaves correctly in the defined behaviour part. In the case commented, the macro __cplusplus
is defined ONLY in C++ (by the compiler itself), and it is as a preprocessor flag to indicate that you are compiling a c++ source. Putting it between the #ifndef __cplusplus
and the following #endif
statements, makes it to exclude for compilation the in between code (normally, because it would lead to a syntactic error or an unsupported feature). Normally, you will find the following construct in some/many C/C++ standard headers in your system (so they can be used in both C and C++):
#ifndef __cplusplus
extern "C" {
#endif
...
#ifndef __cplusplus
}
#endif
to avoid the extern "C" {}
construct, which is C++ specific, and would raise a compiler error in plain C.
NOTE
of course, if you #define __cplusplus
before including any of these files, you'll get your C compiler shouting at you about bad syntax on including such a header file. You can try this yourself to see how it happens:
pru.c
#define __cplusplus 20170301
#include <stdio.h>
int main()
{
printf("Hello, world!\n");
} /* main */
and then compilation of this gives:
$ make pru
cc -O -pipe pru.c -o pru
In file included from pru.c:2:
/usr/include/stdio.h:159:1: error: expected identifier or '('
__BEGIN_DECLS
^
/usr/include/sys/cdefs.h:59:30: note: expanded from macro '__BEGIN_DECLS'
#define __BEGIN_DECLS extern "C" {
^
In file included from pru.c:2:
/usr/include/stdio.h:235:1: error: expected identifier or '('
__BEGIN_DECLS
^
/usr/include/sys/cdefs.h:59:30: note: expanded from macro '__BEGIN_DECLS'
#define __BEGIN_DECLS extern "C" {
^
pru.c:6:2: warning: implicitly declaring library function 'printf' with type 'int (const char *, ...)' [-Wimplicit-function-declaration]
printf("Hello, world!\n");
^
pru.c:6:2: note: include the header <stdio.h> or explicitly provide a declaration for 'printf'
1 warning and 3 errors generated.
*** Error code 1
Stop.
make: stopped in /home/user
Think that you are never going to move the standard header files to another computer to compile your source code. Should you try this, then you would have undefined behaviour, but never while respecting the compiler implementation. This means, you have to accept the compiler makers to use those undefined behaviour things that result in compiler implementation details, but you cannot do that in your code (at least if you don't want to fail into your program doing nasty things)