-unid = c ++ 11未定义“ unix” C ++预处理程序宏

her*_*ung 4 c++ unix preprocessor icc c++11

unixpreproc.cpp

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

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

void main() {}
Run Code Online (Sandbox Code Playgroud)

使用Intel C ++编译器19.0.3:

icpc -o unixpreproc unixpreproc.cpp显示同时定义了unix__unix__

icpc -std=c++11 -o unixpreproc unixpreproc.cpp显示仅__unix__已定义。这是故意的吗?它没有记录在英特尔编译器手册中

Jon*_*ely 6

是的,这是非常故意的。这在GCC手册中进行了解释(其行为与此相同icpc):

C标准要求所有特定于系统的宏都必须是保留名称空间的一部分。所有以两个下划线或下划线和大写字母开头的名称均保留给编译器和库使用,以供其使用。但是,历史上特定于系统的宏的名称没有特殊的前缀。例如,通常会unix在Unix系统上找到定义。对于所有此类宏,GCC提供了一个并行宏,在开头和结尾处添加了两个下划线。如果unix已定义,__unix__也将被定义。下划线永远不会超过两个;的平行度_mips__mips__

当将-ansi选项或-std要求严格符合性的任何选项提供给编译器时,保留名称空间之外的所有系统特定的预定义宏都将被抑制。保留的命名空间中的并行宏保持定义状态。

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

-std=c++11选件要求严格遵守。该-std=gnu++11选项是非严格等效项,它将定义unix__unix__


Sne*_*tel 5

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

当您不指定任何语言标准时,编译器将使用其默认行为,该行为避免严格遵循标准,而向后兼容。