为什么人们在C++中使用__(双下划线)这么多

Nat*_*n W 86 c++ double-underscore

我正在浏览一些开源的C++代码,并注意到代码中使用的分数很多,主要是在变量名称的开头.

return __CYGWIN__;
Run Code Online (Sandbox Code Playgroud)

只是想知道是否有这样的原因,或者只是一些人的代码风格?我认为我很难读.

mac*_*llt 119

来自C++编程,规则和建议:

在标识符中使用两个下划线(`__')保留用于编译器根据ANSI-C标准的内部使用.

下划线(`_')通常用于库函数的名称(例如"_main"和"_exit").为了避免冲突,请不要使用下划线开始标识符.

  • @cz 命名空间无关。系统头可以定义以下划线开头的宏名称,例如“_main”。 (3认同)

CB *_*ley 48

除非他们认为他们是"实施的一部分",即标准库,否则他们不应该.

这些规则非常具体,比其他人建议的要详细一些.

所有包含双下划线或以下划线后跟大写字母开头的标识符都保留用于所有范围的实现,即它们可能用于宏.

此外,所有其他以下划线开头的标识符(即未后跟另一个下划线或大写字母)都保留给全局范围内的实现.这意味着您可以在自己的命名空间或类定义中使用这些标识符.

这就是为什么Microsoft使用具有前导下划线的函数名称以及全部为小写的许多核心运行时库函数,这些函数不属于C++标准.保证这些函数名不会与标准C++函数或用户代码函数冲突.


Jam*_*ran 34

根据C++标准,以一个下划线开头的标识符保留给库.以两个下划线开头的标识符保留给编译器供应商.

  • 更重要的是:保留了在其中任何地方包含双下划线的标识符*.17.4.3.1.2 (17认同)

bog*_*bog 10

上述评论是正确的. __Symbol__通常是由您的有用编译器(或预处理器)供应商提供的魔术令牌.也许最广泛使用的是__FILE____LINE__,它们由C预处理器扩展以指示当前文件名和行号.当你想记录某种程序断言失败时,这很方便,包括错误的文本位置.


Men*_*boy 8

这是"普通"代码中你不应该做的事情.这可确保编译器和系统库可以定义不会与您的符号冲突的符号.


Rem*_*ket 6

双下划线保留给实现

最高投票的答案引用了 C++ 编程:规则和建议

“根据 ANSI-C 标准,标识符中两个下划线 (`__') 的使用保留供编译器内部使用。”

然而,阅读一些C ++和C标准后,我无法找到下划线的任何提及被局限于只是编译器的内部使用。标准更通用,保留双下划线用于实现

C++

C++(当前工作草案,于 2019 年 5 月 26 日访问)在lex.name

  • 每个包含双下划线 __ 或以下划线开头后跟大写字母的标识符都保留给实现以供任何使用。
  • 每个以下划线开头的标识符都保留给实现以用作全局命名空间中的名称。

C

虽然这个问题是针对 C++ 的,但我引用了 C 标准 99 和 17 的相关部分:

C99第 7.1.3 节

  • 所有以下划线和大写字母或另一个下划线开头的标识符始终保留供任何使用。
  • 所有以下划线开头的标识符始终保留用作普通名称空间和标记名称空间中具有文件范围的标识符。

C17和 C99 说的一样。

执行是什么?

对于 C/C++,实现松散地指的是从用户源文件生成可执行文件所需的集合资源。这包括:

  • 预处理器
  • 编译器
  • 链接器
  • 标准库

示例实现

维基百科上提到了许多不同的 C++ 实现。(无锚链接,ctrl+f“实现”)

这是 Digital Mars 的 C/C++ 实现的一个示例,为他们的功能保留了一些关键字。