全局命名空间中的保留名称

时间:2012-03-12 14:27:21

标签: c++ name-resolution

根据我对Dynamic array of objects in C++的回答以及What are the rules about using an underscore in a C++ identifier?的后续行动: 显然,全局命名空间中保留以_开头,后跟大写字母的名称。

  

17.4.3.2.1全局名称[lib.global.names]

     

某些名称和功能签名集始终保留给实现:

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

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

在我对第一个问题的回答中,我有一个看起来像这样的课程

class A
{
 private:
   vector<int> _Ints;
}

在评论中,我被告知_Ints标识符调用未定义的行为,因为它是保留名称。但是,根据最近的标准草案,使用以下规则进行成员变量的名称查找:

  

3.4.3.1班级成员[class.qual]

     

如果 quali fi ed-id 嵌套名称指定指定一个类,则在嵌套名称规范之后指定的名称除了下面列出的情况之外,在类(10.2)的范围内。名字应该   表示该类或其基类之一的一个或多个成员

对我来说,这意味着没有成员变量可以成为全局命名空间的一部分,因为它的范围是类。

现在,问题是:

我的理解是否正确,成员变量永远不会违反实现保留名称规则,因为它们不在全局命名空间中?如果我不正确,有人可以解释我对查询规则的误解吗?

3 个答案:

答案 0 :(得分:6)

_Int明显违反了第一条规则:“每个包含a的名称 双下划线(_ _)或以下划线开头,后跟一个 大写字母(2.11)保留给任何实现 使用。“”任何使用“意味着它所说的:它可以 是预定义的宏,或在编译器中触发一些特殊行为, 或编译器作者想要的任何其他内容。你在哪里都没关系 使用名称,如果你使用它,它是未定义的行为(除非 编译器文档否则说明。

更一般地说,至少在历史上,编译器一直相当宽松, 传统上包含许多系统头文件 名称以单个下划线开头,后跟小写字母。 它也可能是最好的避免这些。 (历史上,甚至,那里 也没有下划线的名字。我知道我有问题 名称linux变为1。看不到任何下划线,但...... 但是,除了更改名称外,您无能为力 当冲突发生时。)

更一般地说,下划线在某些字体中表现不佳, 并且最好在符号的两端避开它们。

答案 1 :(得分:2)

您从标准中引用的规则表明,以下划线后跟大写字母开头的标识符是为任何使用保留的,而不仅仅是在全局命名空间中。因此,不允许命名成员变量_Ints

在全局命名空间中保留以下划线开头的标识符,该下划线后面没有下划线或大写字母。因此,您可以为成员变量_ints命名,但是您不能在全局命名空间中拥有名为_ints的全局变量。

答案 2 :(得分:1)

  

显然_(Upercase Letter)在全局命名空间中保留。

没有。保留无处不在。再次阅读17.4.3.2.1:

  

每个包含双下划线(_ _)的名称或以下划线后跟大写字母(2.11)开头的名称都保留给实现以供任何使用。

根本没有提到“全局命名空间”(全局命名空间仅与后续规则相关)。