C++ 全局作用域中匿名命名空间中的名称是否可以有前导下划线?

C++ 全局作用域中匿名命名空间中的名称是否可以有前导下划线?,c++,C++,根据规范,不允许使用带前导下划线的全局名称: 17.4.3.1.2全局名称 -每个以下划线开头的名称都保留给实现,以用作全局命名空间中的名称 这是否也适用于顶级匿名命名空间中定义的名称?是。但这句话并没有说明这一点(你自己也知道) 以下是我认为适用于此的内容: 17.4.3.1.3外部联动装置 三,。具有两个连续下划线(2.11)的每个名称都保留给实现,以用作外部“C”和外部“C++”链接的名称 我认为它适用于匿名名称空间中使用外部链接声明的变量,但应该注意的是,它讨论的是双下划线。因此: na

根据规范,不允许使用带前导下划线的全局名称:

17.4.3.1.2全局名称
-每个以下划线开头的名称都保留给实现,以用作全局命名空间中的名称


这是否也适用于顶级匿名命名空间中定义的名称?

是。但这句话并没有说明这一点(你自己也知道)

以下是我认为适用于此的内容:

17.4.3.1.3外部联动装置

三,。具有两个连续下划线(2.11)的每个名称都保留给实现,以用作外部“C”和外部“C++”链接的名称

我认为它适用于匿名名称空间中使用外部链接声明的变量,但应该注意的是,它讨论的是双下划线。因此:

namespace
{
   std::string __s1; //not allowed
   std::string _s2;  //allowed (allowed, as I understand)
}
一个更一般的主题:


仅在全局命名空间中保留以前导下划线开头、后跟非大写字母数字字符且不包含双下划线的名称。这是因为在某些系统上,某些名称需要使用前导下划线,或者已经被底层操作系统和/或其C库使用。匿名命名空间中的名称没有此问题


也就是说,我总是想知道为什么人们如此热衷于使用丑陋的名字!除非我处于标准库实现模式(在这种模式下,我必须有效地使用难看的名称,以免与用户名冲突),否则我总是想知道在代码中的任何地方使用前导下划线是否有错!很少有情况下需要使用前导下划线(例如,在调用
\u exit()
或使用
std::bind()
的占位符时),但通常用户不应触摸它们:既不使用也不定义它们。

充其量,它实际上是,如果您决定在任何变量名上使用前导下划线,则格式非常糟糕。@palsm4这是boost bind库定义参数占位符(
\u 1
\u 2
,等等)的方法。未命名的命名空间并不特别;它只是一个普通的、唯一命名的名称空间,带有一个隐式using指令,该指令将其名称注入封闭的名称空间。然而,这里有一个有趣的问题:通过using指令引入全局名称空间的名称是否会违反此规则?@JamesMcNellis确实,这就是我要问的问题。@JamesMcNellis:你的意思是允许使用
\u s2
,但是
\u S3
不允许(强调大写)?spec中的哪一条声明禁止它?请参见您所链接问题的公认答案中第一条引文中的第一个要点。章节标题与此无关。案文规定,此类名称保留供任何使用。这包括“用作宏”,它禁止在用户代码中使用这样的名称。不,当它说“用于任何用途”时,它实际上是指它。看看标准库的头文件,尤其是那些定义类和函数模板的头文件。您会发现,用户代码无法使用的大多数名称(例如,包括防护装置、其他宏、模板参数名称、变量名称等)的格式为
\uuux
\ux
。这是因为这些名称保留给实现以供任何使用。如果这些名称没有保留任何用途,那么用户代码就可以将这些名称定义为宏,而标准库根本无法工作。我完全同意这里表达的观点
+1
从我这里,我碰巧知道这个问题是从中讨论出来的,不是因为我想使用这些名称,而是因为这样的问题可能会被成千上万的其他用户看到,我觉得至少提及这一点很重要。