从What are the rules about using an underscore in a c identifier读取anwser我偶然发现了以下引文:
从2003 C ++标准:
17.4.3.2.1全局名称[lib.global.names]
某些名称和功能签名集始终保留给实现:
- 包含双下划线(_ _)或以下划线后跟大写字母(2.11)开头的每个名称都保留给实现以供任何使用。
- 以下划线开头的每个名称都保留给实现,以用作全局命名空间中的名称。 165
165)这些名称也在namespace :: std(17.4.3.1)中保留。
为实施保留究竟是什么意思?
答案 0 :(得分:7)
正是这个意思。这意味着,如果您要提供编译器或标准库实现,则只允许创建此类名称。
答案 1 :(得分:7)
"实施"指的是C ++语言"的实现。它包含执行C ++程序所需的一切:编译器,标准库,要执行的硬件,操作系统,可视化系统,输入等。
有问题的限制意味着您的编译器可能会在不告知您的情况下预定义保留表单的名称,或者您的标准库实现可能会这样做。例如,您的标准库可能会定义宏__Foo
,因此如果您尝试在源代码中使用__Foo
作为标识符,那么您实际上最终会使用宏替换。
保留名称的目的是为您的编译器和标准库提供在纯C ++中表达功能的自由,而不必担心与用户代码引入名称冲突。
有关如何在实践中使用它的生动示例,只需查看标准库实现的任何头文件。
实际上,一些保留名称已经定义为明确定义的公共设施:__FILE__
,__cplusplus
,__VA_ARGS__
,仅举几例。 C语言(对保留标识具有相同规则)一直使用保留名称来引入新关键字(例如_Bool
)。
答案 2 :(得分:5)
实现这里意味着编译器(比如gcc,msvc等)的组合,标准库(说明语言中包含哪些功能),操作系统(Windows,Mac等)和硬件(Intel,ARM等)。
根据实现,定义了某些值,编译器使用这些值来生成特定于实现的目标代码。例如
__TARGET_ARCH_ARM is defined by RealView #Matches first case
_M_ARM is defined by Visual Studio #Matches second case
识别CPU制造商。
简而言之,这些条款旨在阻止您使用上述格式的宏。
事实上, n3797-> 17.6.5.3对宏定义的限制表示,如果您希望定义上述格式的宏,它们是:
适用于#if预处理指令,除非明确说明 另有说明。
示例:
#ifndef _M_ARM
#define _M_ARM // Say you're compiling for another platform
#endif
注意
保留用于实现的宏不限于所提到的格式。例如,__arm__
由gcc定义以标识制造商。