为什么人们在 C++ 中如此频繁地使用 __(double underscore)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/224397/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 13:51:18  来源:igfitidea点击:

Why do people use __(double underscore) so much in C++

c++double-underscore

提问by Nathan W

I was having a look through some open source C++ code and notice a lot of double under scores where used in the code, mainly at the start of variable names.

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

return __CYGWIN__;

Just wondering is there a reason for this, or is it just some people code styles? I would think that I makes it hard to read.

只是想知道这是有原因的,还是只是某些人的代码风格?我会认为我很难阅读。

回答by maccullt

From Programming in C++, Rules and Recommendations:

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

The use of two underscores (`__') in identifiers is reserved for the compiler's internal use according to the ANSI-C standard.

Underscores (`_') are often used in names of library functions (such as "_main" and "_exit"). In order to avoid collisions, do not begin an identifier with an underscore.

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

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

回答by CB Bailey

Unless they feel that they are "part of the implementation", i.e. the standard libraries, then they shouldn't.

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

The rules are fairly specific, and are slightly more detailed than some others have suggested.

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

All identifiers that contain a double underscore or start with an underscore followed by an uppercase letter are reserved for the use of the implementation at all scopes, i.e. they might be used for macros.

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

In addition, all other identifiers which start with an underscore (i.e. not followed by another underscore or an uppercase letter) are reserved for the implementation at the global scope. This means that you can use these identifiers in your own namespaces or in class definitions.

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

This is why Microsoft use function names with a leading underscore and all in lowercase for many of their core runtime library functions which aren't part of the C++ standard. These function names are guaranteed not to clash with either standard C++ functions or user code functions.

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

回答by James Curran

According to the C++ Standard, identifiers starting with one underscore are reserved for libraries. Identifiers starting with two underscores are reserved for compiler vendors.

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

回答by bog

The foregoing comments are correct. __Symbol__is generally a magic token provided by your helpful compiler (or preprocessor) vendor. Perhaps the most widely-used of these are __FILE__and __LINE__, which are expanded by the C preprocessor to indicate the current filename and line number. That's handy when you want to log some sort of program assertion failure, including the textual location of the error.

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

回答by Menkboy

It's something you're not meant to do in 'normal' code. This ensures that compilers and system libraries can define symbols that won't collide with yours.

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

回答by RemarkableBucket

Double underscores are reserved to the implementation

双下划线保留给实现

The top voted answer cites Programming in C++: Rules and Recommendations:

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

"The use of two underscores (`__') in identifiers is reserved for the compiler's internal use according to the ANSI-C standard."

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

However, after reading a few C++ and C standards, I was unable to find any mention of underscores being restricted to justthe compiler's internal use. The standards are more general, reserving double underscores for the implementation.

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

C++

C++

C++(current working draft, accessed 2019-5-26) states in lex.name:

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

  • Each identifier that contains a double underscore __ or begins with an underscore followed by an uppercase letter is reserved to the implementation for any use.
  • Each identifier that begins with an underscore is reserved to the implementation for use as a name in the global namespace.
  • 每个包含双下划线 __ 或以下划线开头后跟大写字母的标识符都保留给实现以供任何使用。
  • 每个以下划线开头的标识符都保留给实现以用作全局命名空间中的名称。

C

C

Although this question is specific to C++, I've cited relevant sections from C standards 99 and 17:

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

C99section 7.1.3

C99第 7.1.3 节

  • All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.
  • All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces.
  • 所有以下划线和大写字母或另一个下划线开头的标识符始终保留供任何使用。
  • 所有以下划线开头的标识符始终保留用作普通名称空间和标记名称空间中具有文件范围的标识符。

C17says the same thing as C99.

C17和 C99 说的一样。

What is the implementation?

执行是什么?

For C/C++, the implementationloosely refers to the set resources necessary to produce an executable from user source files. This includes:

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

  • preprocessor
  • compiler
  • linker
  • standard library
  • 预处理器
  • 编译器
  • 链接器
  • 标准库

Example implementations

示例实现

There are a number of different C++ implementations mentioned on Wikipedia. (no anchor link, ctrl+f "implementation")

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

Here's an example of Digital Mars' C/C++ implementation reserving some keywords for a feature of theirs.

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

回答by Sqeaky

In addition to libraries which many other people responded about, Some people also name macros or #define values for use with the preprocessor. This would make it easier to work with, and may have allowed bugs in older compilers to be worked around.

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

Like others mentioned, it helps prevent name collision and helps to delineate between library variables and your own.

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