在C++标识符中使用下划线有什么规则?

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

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

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

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

2003 C++标准:

17.4.3.1.2全局名称[lib.Global.names]

某些名称和函数签名集始终保留给实现:

  • 每个名称包含双下划线(\uu)或以下划线开头,后跟大写字母(2.11)的名称都保留给实现以供任何使用
  • 每个以下划线开头的名称都保留给实现,以用作全局命名空间中的名称。165

165)此类名称也保留在名称空间::std(17.4.3.1)中

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

7.1.3保留标识符

每个标题声明或定义其关联子标题中列出的所有标识符,以及
(可选)声明或定义在其关联的未来库方向子类中列出的标识符,以及始终保留用于任何用途或用作文件范围标识符的标识符

  • 以下划线和大写字母或其他字母开头的所有标识符
    下划线始终保留供任何使用
  • 所有以下划线开头的标识符始终保留用作标识符
    文件范围在普通和标记名空间中
  • 以下任何子类(包括未来库)中的每个宏名称
    如果包含任何相关标题,则按照规定保留使用;
    除非另有明确规定(见7.1.4)
  • 以下任何子条款中具有外部链接的所有标识符(包括
    未来库方向)始终保留用作外部库的标识符
    联动装置。154
  • 以下任何子条款中列出的具有文件范围的每个标识符(包括
    保留将来的库方向)以用作宏名称和标识符
    如果包含任何关联的标头,则文件作用域位于相同的名称空间中

没有保留其他标识符。如果程序在
保留的上下文(7.1.4允许的除外),或定义保留
标识符作为宏名称,行为未定义

如果程序删除(使用#undef)第一行中标识符的任何宏定义
在上面列出的组中,行为未定义

154)具有外部链接的保留标识符列表包括errnomath\u errhandlingsetjmpva\u end

其他限制可能适用。例如,POSIX标准保留了许多可能在普通代码中显示的标识符:

  • 以大写字母E开头的名称后跟数字或大写字母:
    • 可用于其他错误代码名称
  • isto开头,后跟小写字母的名称
    • 可用于其他字符测试和转换功能
  • LC\uu开头,后跟大写字母的名称
    • 可用于指定区域设置属性的其他宏
  • 所有后缀为fl的现有数学函数的名称均保留
    • 对于分别在浮点和长双参数上操作的相应函数
  • 保留以SIG开头,后跟大写字母的名称
    • 获取其他信号名称
  • 保留以SIG开头,后跟大写字母的名称
    • 用于其他信号操作
  • 保留以strmemwcs开头并后跟小写字母的名称
    • 用于其他字符串和数组函数
  • 保留以PRISCN开头,后跟任何小写字母或X的名称
    • 对于其他格式说明符宏
  • 保留以\u t结尾的名称
    • 用于其他类型名称

虽然现在将这些名称用于您自己的目的可能不会引起问题,但它们确实会增加与该标准未来版本冲突的可能性


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

在对本文进行研究之后,我不再以\u t
因为这是POSIX标准保留的

关于任何以\u t结尾的标识符的规则让我非常惊讶。我认为这是一个POSIX标准(目前还不确定),寻求澄清和正式的章节。这是GNULibtool手册中列出的保留名称

CesarB提供了到POSIX 2004保留符号的以下链接,并指出许多其他保留前缀和后缀。。。可以在那里找到。这个
这里定义了POSIX 2008保留符号。与上述限制相比,这些限制更加微妙

发表评论