c++ - 在 C++ 标识符中使用下划线的规则是什么?

标签 c++ naming-conventions standards c++-faq

在 C++ 中,使用某种前缀来命名成员变量是很常见的,以表示它们是成员变量,而不是局部变量或参数。如果您有 MFC 背景,您可能会使用 m_foo。我也偶尔看到过myFoo

C#(或者可能只是 .NET)似乎建议只使用下划线,如 _foo。这是 C++ 标准允许的吗?

最佳答案

规则(在 C++11 中没有改变):

  • 在任何范围内保留,包括用作 implementation宏:
    • 以下划线开头的标识符,后跟一个大写字母
    • 包含相邻下划线(或“双下划线”)的标识符
  • 保留在全局命名空间中:
    • 以下划线开头的标识符
  • 此外,std 命名空间中的所有内容都是保留的。 (不过,您可以添加模板特化。)

来自 2003 C++ 标准:

17.4.3.1.2 Global names [lib.global.names]

Certain sets of names and function signatures are always reserved to the implementation:

  • Each name that contains a double underscore (__) or begins with an underscore followed by an uppercase letter (2.11) is reserved to the implementation for any use.
  • Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.165

165) Such names are also reserved in namespace ::std (17.4.3.1).

因为 C++ 基于 C 标准(1.1/2,C++03),而 C99 是规范性引用(1.2/1,C++03),这些也适用于 1999 年的 C 标准:

7.1.3 Reserved identifiers

Each header declares or defines all identifiers listed in its associated subclause, and optionally declares or defines identifiers listed in its associated future library directions subclause and identifiers which are always reserved either for any use or for use as file scope identifiers.

  • 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.
  • Each macro name in any of the following subclauses (including the future library directions) is reserved for use as specified if any of its associated headers is included; unless explicitly stated otherwise (see 7.1.4).
  • All identifiers with external linkage in any of the following subclauses (including the future library directions) are always reserved for use as identifiers with external linkage.154
  • Each identifier with file scope listed in any of the following subclauses (including the future library directions) is reserved for use as a macro name and as an identifier with file scope in the same name space if any of its associated headers is included.

No other identifiers are reserved. If the program declares or defines an identifier in a context in which it is reserved (other than as allowed by 7.1.4), or defines a reserved identifier as a macro name, the behavior is undefined.

If the program removes (with #undef) any macro definition of an identifier in the first group listed above, the behavior is undefined.

154) The list of reserved identifiers with external linkage includes errno, math_errhandling, setjmp, and va_end.

其他限制可能适用。例如,POSIX 标准保留了很多可能出现在正常代码中的标识符:

  • 以大写 E 开头的名称后跟数字或大写字母:
    • 可用于其他错误代码名称。
  • isto 开头后跟小写字母的名称
    • 可用于额外的字符测试和转换功能。
  • LC_ 开头后跟大写字母的名称
    • 可用于指定语言环境属性的其他宏。
  • 保留所有以 fl 为后缀的现有数学函数的名称
    • 分别适用于对 float 和 long double 参数进行操作的相应函数。
  • 保留以 SIG 后跟大写字母开头的名称
    • 获取其他信号名称。
  • 保留以 SIG_ 后跟大写字母开头的名称
    • 用于其他信号操作。
  • 保留以 strmemwcs 后跟小写字母开头的名称
    • 用于其他字符串和数组函数。
  • 保留以 PRISCN 开头的名称,后跟任何小写字母或 X
    • 用于其他格式说明符宏
  • 保留以 _t 结尾的名称
    • 用于其他类型名称。

虽然现在将这些名称用于您自己的目的可能不会造成问题,但它们确实会增加与该标准的 future 版本发生冲突的可能性。


就我个人而言,我只是不使用下划线开头的标识符。我的新规则:不要在任何地方使用双下划线,这很容易,因为我很少使用下划线。

在对本文进行研究后,我不再以 _t 结束我的标识符 因为这是 POSIX 标准保留的。

关于任何以 _t 结尾的标识符的规则让我很惊讶。我认为这是一个 POSIX 标准(尚不确定),正在寻找澄清和官方章节。这是来自 GNU libtool manual ,列出保留名称。

CesarB 提供了 POSIX 2004 的以下链接保留符号和注释“可以在那里找到许多其他保留的前缀和后缀……”。这 POSIX 2008保留符号在这里定义。这些限制比上面的要微妙一些。

关于c++ - 在 C++ 标识符中使用下划线的规则是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/228783/

相关文章:

c++ - 如何保证进程调用malloc()时立即分配物理内存?

c++ - 是否可以使用 try/catch 捕获段错误?

c++ - 在 C++ 中为有向图创建邻接表

c - 没有定义函数参数类型默认为int?我疯了吗?

c++ - C++ : 中用于 GUI 的 WXwidgets

java - 始终使用 Java Beans 命名约定是个好主意吗?

c++ - 哪个参数应该首先是 `old` 或 `new` ?

ruby - MiniTest::Spec 文件应该如何命名?

c - C 预处理器的 Null 指令有什么意义?

c++ - 侵犯隐私 - C++ 标准如何处理它?