99

我正在查看一些开源 C++ 代码,我注意到代码中使用了很多双下划线,主要是在变量名的开头。

return __CYGWIN__;

只是想知道:这是有原因的,还是只是某些人的代码风格?我认为它使阅读变得困难。

4

7 回答 7

136

来自C++ 编程、规则和建议

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

下划线 (`_') 经常用于库函数的名称中(例如“_main”和“_exit”)。为避免冲突,请勿使用下划线开头的标识符。

于 2008-10-22T03:45:05.090 回答
52

除非他们觉得自己是“实现的一部分”,即标准库,否则他们不应该这样做。

这些规则相当具体,并且比其他一些人建议的要详细一些。

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

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

这就是为什么 Microsoft 使用带有前导下划线且全部小写的函数名称来表示其许多不属于 C++ 标准的核心运行时库函数。保证这些函数名称不会与标准 C++ 函数或用户代码函数发生冲突。

于 2008-10-22T11:15:24.620 回答
39

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

于 2008-10-22T03:42:25.313 回答
11

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

于 2008-10-22T03:49:24.287 回答
8

这是您在“正常”代码中不应该做的事情。这确保编译器和系统库可以定义不会与您的符号冲突的符号。

于 2008-10-22T03:39:48.003 回答
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++,实现松散地指的是从用户源文件生成可执行文件所需的集合资源。这包括:

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

示例实现

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

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

于 2019-05-31T04:56:15.117 回答
3

除了许多其他人回应的库之外,有些人还命名宏或#define 值以与预处理器一起使用。这将使它更容易使用,并且可能允许解决旧编译器中的错误。

像其他人提到的那样,它有助于防止名称冲突,并有助于在库变量和您自己的变量之间进行描述。

于 2008-10-22T03:50:11.680 回答