5

源于我对C++ 中的对象的动态数组的回答,以及关于在 C++ 标识符中使用下划线的规则是什么?:显然,_以大写字母开头的名称被保留在全局命名空间中。

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]

如果qualified -id的nested-name- specifier 指定了一个类,则在该nested-namespeciifier之后指定的名称将在类的范围内查找 (10.2),但下面列出的情况除外。该名称应代表该类或其基类之一的一个或多个成员

对我来说,这意味着任何成员变量都不能成为全局命名空间的一部分,因为它的作用域是类。

现在,问题是:

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

4

3 回答 3

6

_Int显然违反了第一条规则:“每个包含双下划线 (_ _) 或以下划线后跟大写字母 (2.11) 的名称都保留给实现以供任何使用。” “任何使用”的意思就是它所说的:它可以是一个预定义的宏,或者在编译器中触发一些特殊行为,或者编译器作者想要的任何其他东西。不管你在哪里使用这个名字,如果你使用它,它就是未定义的行为(除非编译器文档另有说明)。

更一般地说,至少从历史上看,编译器相当松懈,并且许多系统头文件传统上包含名称以单个下划线后跟一个小写字母开头的宏。最好也避免这些。(从历史上看,甚至也有没有下划线的名字。我知道我的名字linux变成1了 .发生冲突时的名称。)

更一般地说,下划线在某些字体中的显示效果不是很好,最好避免在符号的两端使用它们。

于 2012-03-12T14:38:35.830 回答
3

您从标准中引用的规则指出,以下划线后跟大写字母开头的标识符保留用于任何 use,而不仅仅是在全局命名空间中。所以命名一个成员变量_Ints是不允许的。

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

于 2012-03-12T14:37:20.073 回答
1

显然 _(大写字母) 保留在全局命名空间中。

不,它到处都是保留的。再次阅读 17.4.3.2.1:

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

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

于 2012-03-12T14:38:08.870 回答