Search code examples
c++c++11unixpreprocessoricc

"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.


Solution

  • 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__.