Rog*_*mbe 906 c++ standards naming-conventions c++-faq
在C++中通常用某种前缀命名成员变量来表示它们是成员变量而不是局部变量或参数.如果你来自MFC背景,你可能会使用m_foo.我myFoo偶尔也见过.
C#(或者可能只是.NET)似乎建议只使用下划线,如_foo.这是否允许C++标准?
Mar*_*ork 822
规则(在C++ 11中没有改变):
std命名空间中的所有内容都保留.(但是,您可以添加模板特化.)从2003 C++标准:
17.4.3.1.2全局名称[lib.global.names]
某些名称和函数签名集始终保留给实现:
- 每个包含双下划线(
__)或以下划线后跟大写字母(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)与外部连接保留的标识符的列表包括
errno,math_errhandling,setjmp,和va_end.
其他限制可能适用.例如,POSIX标准保留了许多可能以正常代码显示的标识符:
E大写字母开头的名称后跟数字或大写字母:
is或to后跟小写字母的名称
LC_后跟大写字母
f或l保留
SIG以大写字母开头的名称将被保留
SIG_以大写字母开头的名称将被保留
str,mem或者wcs后跟一个小写字母被保留
PRI或SCN后跟或X保留
_t是保留的
虽然现在将这些名称用于您自己的目的可能不会导致问题,但它们确实会增加与该标准的未来版本冲突的可能性.
就个人而言,我只是不用下划线开始标识符.我的规则的新增内容:不要在任何地方使用双下划线,这很容易,因为我很少使用下划线.
在对本文进行研究后,我不再使用_t
POSIX标准保留标识符.
关于任何标识符的规则以_t令我惊讶的方式结束.我认为这是一个POSIX标准(尚不确定)寻找澄清和官方章节和经文.这来自GNU libtool手册,列出了保留名称.
CesarB提供了以下指向POSIX 2004保留符号的链接,并注意到"可以在那里找到许多其他保留的前缀和后缀......".该 POSIX 2008保留符号在这里被定义.这些限制比上述限制更微妙.
pae*_*bal 192
避免名称冲突的规则都是C++标准(参见Stroustrup书)和C++大师(Sutter等)提到的.
因为我不想处理案件,并且想要一个简单的规则,我设计了一个简单而正确的个人案例:
命名符号时,如果您符合以下条件,则可避免与编译器/ OS /标准库冲突:
当然,将代码放在一个唯一的命名空间中也有助于避免冲突(但不能防止恶意宏)
(我使用宏,因为它们是C/C++符号的代码污染更多,但它可以是从变量名到类名的任何东西)
#define _WRONG
#define __WRONG_AGAIN
#define RIGHT_
#define WRONG__WRONG
#define RIGHT_RIGHT
#define RIGHT_x_RIGHT
Run Code Online (Sandbox Code Playgroud)
从n3242.pdf文件(我希望最终的标准文本类似):
17.6.3.3.2全局名称[global.names]
某些名称和函数签名集始终保留给实现:
- 包含双下划线_ _或以下划线后跟大写字母(2.12)开头的每个名称都保留给实现以供任何使用.
- 以下划线开头的每个名称都保留给实现,以用作全局名称空间中的名称.
但是也:
17.6.3.3.5用户定义的文字后缀[usrlit.suffix]
不以下划线开头的文字后缀标识符保留用于将来的标准化.
最后一个条款令人困惑,除非您认为如果未在全局命名空间中定义,以一个下划线开头并后跟一个小写字母的名称将为Ok ...
Rog*_*mbe 35
来自MSDN:
在标识符的开头使用两个连续的下划线字符(__),或者在大写字母中为C++实现保留单个前导下划线后跟大写字母.对于具有文件范围的名称,应避免使用一个前导下划线后跟小写字母,因为可能与当前或将来的保留标识符冲突.
这意味着您可以使用单个下划线作为成员变量前缀,只要它后面跟一个小写字母.
这显然取自C++标准的第17.4.3.1.2节,但我无法在线找到完整标准的原始来源.
另见这个问题.
Max*_*ert 24
至于问题的另一部分,通常将下划线放在变量名的末尾,以免与内部任何内容发生冲突.
我甚至在类和名称空间内执行此操作,因为我只需要记住一条规则(与"在全局范围内的名称末尾,以及其他地方名称的开头"相比).