在C+&#x2B中使用下划线的规则是什么。标识符?
在C ++中常见的是将成员变量命名具有某种前缀的成员变量,以表示它们是成员变量而不是局部变量或参数的事实。如果您来自MFC背景,则可能会使用 M_FOO
。我还偶尔也看过 myfoo
。
C#(或可能只是.NET)似乎建议仅使用下划线,例如 _foo
。这是C ++标准允许的吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
规则(在C ++ 11中没有更改):
std
名称空间中的所有内容。 (不过,您可以添加模板专业化。)从2003 C ++标准开始:
C ++语言基于C语言(1.1/2,C ++ 03),而C99是标准参考(1.2/1,C ++ 03),因此了解1999 C标准的限制很有用(尽管它们不直接适用于C ++):
其他限制可能适用。例如,POSIX标准保留许多可能以正常代码显示的标识符:
e
开头的名称遵循数字或大写字母:开头的名称为
或 ,然后是小写字母:lc _
开头的名称,然后是大写字母:sig
开头的名称,然后保留大写字母:sig _
开始的名称,然后保留大写字母:开始
,mem
或wcs
,然后保留一个小写字母:开始pri
或scn
,然后保留任何小写字母或x
:_T
结尾的 名称,请保留:尽管现在出于您自己的目的使用这些名称可能不会引起问题,但它们确实增加了与该标准的未来版本发生冲突的可能性。
就我个人而言,我只是没有开始使用下划线标识符。我规则的新增加:不要在任何地方使用双重下划线,这很容易,因为我很少使用下划线。
在对本文进行研究之后,我不再使用
_T
结束标识符因为这是由POSIX标准保留的。
任何标识符以
_T
结尾的规则令我感到惊讶。我认为这是一个Posix标准(尚不确定),以寻找澄清以及官方章节和经文。这是从 gnu libtool手册 。cesarb提供了以下链接,指向 posix 2008 保留的符号在此处定义。这些限制比上面的限制更为细微。
The rules (which did not change in C++11):
std
namespace is reserved. (You are allowed to add template specializations, though.)From the 2003 C++ Standard:
The C++ language is based on the C language (1.1/2, C++03), and C99 is a normative reference (1.2/1, C++03), so it's useful to know the restrictions from the 1999 C Standard (although they do not apply to C++ directly):
Other restrictions might apply. For example, the POSIX standard reserves a lot of identifiers that are likely to show up in normal code:
E
followed a digit or uppercase letter:is
orto
followed by a lowercase letter:LC_
followed by an uppercase letter:f
orl
are reserved:SIG
followed by an uppercase letter are reserved:SIG_
followed by an uppercase letter are reserved:str
,mem
, orwcs
followed by a lowercase letter are reserved:PRI
orSCN
followed by any lowercase letter orX
are reserved:_t
are reserved:While using these names for your own purposes right now might not cause a problem, they do raise the possibility of conflict with future versions of that standard.
Personally I just don't start identifiers with underscores. New addition to my rule: Don't use double underscores anywhere, which is easy as I rarely use underscore.
After doing research on this article I no longer end my identifiers with
_t
as this is reserved by the POSIX standard.
The rule about any identifier ending with
_t
surprised me a lot. I think that is a POSIX standard (not sure yet) looking for clarification and official chapter and verse. This is from the GNU libtool manual, listing reserved names.CesarB provided the following link to the POSIX 2004 reserved symbols and notes 'that many other reserved prefixes and suffixes ... can be found there'. The
POSIX 2008 reserved symbols are defined here. The restrictions are somewhat more nuanced than those above.
避免名称相撞的规则都在C ++标准中(请参阅Stroustrup Book),并由C ++ Gurus(Sutter等)提到。
个人规则
是因为我不想处理案件,并且想要一个简单的规则,所以我设计了一个简单而正确的个人:
命名符号时,如果您:,您将避免与编译器/OS/标准库发生碰撞:
当然,将您的代码放在唯一的名称空间中也有助于避免碰撞(但不会防止邪恶的宏)
一些示例
(我使用宏,因为它们是C/C ++符号的更高代码污染,但这可能是从变量名到class名称的任何内容)
从
n3242.pdf 文件(我希望最终的标准文本相似):
但是也:
最后一个子句令人困惑,除非您考虑一个以一个下划线开头的名称,然后再说一个小写字母,如果在全球名称空间中定义了 not> not>
The rules to avoid collision of names are both in the C++ standard (see Stroustrup book) and mentioned by C++ gurus (Sutter, etc.).
Personal rule
Because I did not want to deal with cases, and wanted a simple rule, I have designed a personal one that is both simple and correct:
When naming a symbol, you will avoid collision with compiler/OS/standard libraries if you:
Of course, putting your code in an unique namespace helps to avoid collision, too (but won't protect against evil macros)
Some examples
(I use macros because they are the more code-polluting of C/C++ symbols, but it could be anything from variable name to class name)
Extracts from C++0x draft
From the n3242.pdf file (I expect the final standard text to be similar):
But also:
This last clause is confusing, unless you consider that a name starting with one underscore and followed by a lowercase letter would be Ok if not defined in the global namespace...
来自 msdn :
这意味着您可以将单个下划线作为成员变量前缀,只要接下来是下案字母。
这显然是从C ++标准的第17.4.3.1.2节中获取的,但是我找不到完整标准在线的原始来源。
另请参见这个问题。
From MSDN:
This means that you can use a single underscore as a member variable prefix, as long as it's followed by a lower-case letter.
This is apparently taken from section 17.4.3.1.2 of the C++ standard, but I can't find an original source for the full standard online.
See also this question.
至于问题的另一部分,通常将变量名称的 end score放在变量名称的上,以与内部任何内容不冲突。
我甚至在课堂和名称空间内都这样做,因为我只需要记住一个规则(与“在全局范围中的名称的末尾,以及其他地方的名称的开始”)。
As for the other part of the question, it's common to put the underscore at the end of the variable name to not clash with anything internal.
I do this even inside classes and namespaces because I then only have to remember one rule (compared to "at the end of the name in global scope, and the beginning of the name everywhere else").
是的,可以在标识符中的任何地方使用下划线。我相信规则是:第一个字符中的AZ,AZ,_中的任何一个,以及以下字符的 +0-9。
下划线前缀在C代码中很常见 - 单个下划线表示“私有”,并且通常保留编译器的双重下划线。
Yes, underscores may be used anywhere in an identifier. I believe the rules are: any of a-z, A-Z, _ in the first character and those +0-9 for the following characters.
Underscore prefixes are common in C code -- a single underscore means "private", and double underscores are usually reserved for use by the compiler.
首先,当前工作草案中的规则在 [lex.name] p3 << /a>:
此外,标准库保留在
名称空间std
和一些僵尸名称中定义的所有名称;请参阅 [Reserved.names.general] 。Posix呢?
正如公认的答案所指出的那样,实现的其他部分,例如POSIX标准,它限制了您可以使用的标识符。
v2_chap02.html“ rel =“ nofollow noreferrer”> posix 2008标准,2.2.2
在C ++中,几乎所有与POSIX相关的问题都可以通过命名空间来避免。
这也是为什么C ++标准可以添加诸如
std :: enable_if_t
之类的符号,而不会破坏POSIX的兼容性。可视化
y
的上述规则适用于命名和未命名的名称空间。无论哪种方式,在以下名称空间中,全局名称空间的规则
不再应用(请参阅 [namespace.unamed] )。
y
的上述规则还适用于类,功能等中的标识符。除了全球范围外。即使
断言
在此处不像功能风格的宏一样使用,但该名称已保留。这也是为什么到目前为止取得了一些成功。推荐的练习
要安全,始终避免双重下降,并始终避免使用领先的下划线。
在某些情况下,后者还可以,但是很难记住这些规则,而且要安全比后悔要好。
_
本身呢?有些人使用
_
表示未使用某些变量或功能参数。但是,您可以避免以下内容:您也可以施放参数
p
tovoid
喜欢(void)p
,如果这是关于沉默警告关于p
未使用,您需要C兼容性。请参阅为什么为什么将未使用的返回值投入到void?。Firstly, the rules in current working draft are laid out in [lex.name] p3:
Furthermore, the standard library reserves all names defined in
namespace std
and some zombie names; see [reserved.names.general].What about POSIX?
As the accepted answer has pointed out, there may be other parts of the implementation, like the POSIX standard, which limit the identifiers you can use.
- POSIX 2008 Standard, 2.2.2
In C++, almost all problems associated with POSIX can be avoided through namespaces.
This is also why the C++ standard can add tons of symbols like
std::enable_if_t
without breaking POSIX compatibility.Visualization
The above rules for
y
apply to both named and unnamed namespaces.Either way, in the following namespace, the rules of the global namespace
no longer apply (see [namespace.unnamed]).
The above rules for
y
also apply to identifiers in classes, functions, etc.; anything but global scope.Even though
assert
isn't used like a function-style macro here, the name is reserved. This is also why proposal P2884 contemplates making it a keyword in C++26, with some success so far.Recommended Practice
To be safe, always avoid double underscores, and always avoid nams with leading underscores.
The latter are okay in some cases, but it's difficult to memorize these rules, and it's better to be safe than sorry.
What about
_
in itself?Some people use
_
to indicate that some variable or function parameter isn't used. However, you can avoid this with:You can also cast a parameter
p
tovoid
like(void)p
, if this is about silencing warnings aboutp
being unused, and you need C compatibility. See Why cast unused return values to void?.