"unix" C++ 预处理器宏未定义为 -std=c++11

"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() {}

使用英特尔 C++ 编译器 19.0.3:

icpc -o unixpreproc unixpreproc.cpp 表明 unix__unix__ 宏都被定义了

但是

icpc -std=c++11 -o unixpreproc unixpreproc.cpp表示只定义了__unix__。这是故意的吗?是not documented in the Intel compiler manual.

我认为这是故意的,是的。在 C++11 标准(和其他正式发布的 C++ 标准)下,符合标准的编译器不能声明他们想要的任何宏和其他全局符号,因为这些可能会干扰程序对这些名称的使用。在特定的标准保留名称列表(不包括 unix)之外,编译器必须使用以双下划线开头的宏名称,保留供编译器使用。

当您未指定任何语言标准时,编译器将采用其默认行为,避免严格遵守标准以支持向后兼容性。

是的,这是非常刻意的。这在 GCC 手册中有解释(在这方面与 icpc 的行为相同):

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.

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

-std=c++11 选项要求严格遵守。 -std=gnu++11 选项是非严格等效项,它将定义 unix 以及 __unix__.