【问题标题】:"unix" C++ preprocessor macro is undefined with -std=c++11“unix” C++ 预处理器宏未使用 -std=c++11 定义
【发布时间】:2019-08-01 08:34:36
【问题描述】:

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

【问题讨论】:

  • 似乎是文档中的疏忽。请注意,如果使用了-std=gnu++11,则定义了unix

标签: c++ c++11 unix preprocessor icc


【解决方案1】:

是的,这是非常刻意的。这在 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__

【讨论】:

  • 优秀的 GCC 文档!根据您的回答,对我来说最好的方法是使用-std=c++11 并切换到使用#ifdef __unix__
【解决方案2】:

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

当您未指定任何语言标准时,编译器将使用其默认行为,这会避开严格的标准合规性以支持向后兼容性。

【讨论】:

    猜你喜欢
    • 2011-01-26
    • 1970-01-01
    • 2010-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-10
    相关资源
    最近更新 更多