Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"unix" C++ preprocessor macro is undefined with -std=c++11

unixpreproc.cpp

#ifdef unix
#warning "unix is defined"
#endif

#ifdef __unix__
#warning "__unix__ is defined"
#endif

void main() {}

Using Intel C++ compiler 19.0.3:

icpc -o unixpreproc unixpreproc.cpp shows that both unix and __unix__ macros are defined

but

icpc -std=c++11 -o unixpreproc unixpreproc.cpp shows that only __unix__ is defined. Is this deliberate? It is not documented in the Intel compiler manual.

like image 884
hertzsprung Avatar asked Aug 01 '19 08:08

hertzsprung


2 Answers

Yes, it's very deliberate. This is explained in the GCC manual (which behaves the same as icpc in this respect):

The C standard requires that all system-specific macros be part of the reserved namespace. All names which begin with two underscores, or an underscore and a capital letter, are reserved for the compiler and library to use as they wish. However, historically system-specific macros have had names with no special prefix; for instance, it is common to find unix defined on Unix systems. For all such macros, GCC provides a parallel macro with two underscores added at the beginning and the end. If unix is defined, __unix__ will be defined too. There will never be more than two underscores; the parallel of _mips is __mips__.

When the -ansi option, or any -std option that requests strict conformance, is given to the compiler, all the system-specific predefined macros outside the reserved namespace are suppressed. The parallel macros, inside the reserved namespace, remain defined.

See https://gcc.gnu.org/onlinedocs/cpp/System-specific-Predefined-Macros.html

The -std=c++11 option requests strict conformance. The -std=gnu++11 option is the non-strict equivalent, which will define unix as well as __unix__.

like image 174
Jonathan Wakely Avatar answered Nov 04 '22 00:11

Jonathan Wakely


I would assume this is deliberate, yes. Under the C++11 standard (and the other formally published C++ standards), conforming compilers cannot declare whatever macros and other global symbols they want, because those could interfere with the program's use of those names. Outside the specific list of standard reserved names (which does not include unix), compilers must use macro names starting with a double underscore, which are reserved for the compiler's use.

When you don't specify any language standard the compiler is going with its default behavior, which eschews strict standards compliance in favor of backwards compatibility.

like image 5
Sneftel Avatar answered Nov 03 '22 22:11

Sneftel