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

Reserved names in the global namespace

本文关键字:保留 命名空间 全局      更新时间:2023-10-16

源于我对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]

如果限定id嵌套名称指定器指定了一个类,则在该类的范围内查找嵌入名称指定器之后指定的名称(10.2),但下列情况除外。名称应代表该类或其基类的一个或多个成员

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

现在,问题是:

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

_Int明显违反了第一条规则:“每个包含双下划线(__)或以下划线开头,后跟大写字母(2.11)保留给任何使用”ldquo;任何用途";确切地说:它可以是预定义的宏或者触发编译器中的一些特殊行为,或者编译器作者想要的任何其他东西。你在哪里并不重要使用名称,如果使用该名称,则它是未定义的行为(除非编译器文档另有说明)。

更普遍地说,至少在历史上,编译器一直相当松懈,并且许多系统头传统上包括具有名称以一个下划线开头,后跟一个小写字母。最好还是避开那些。(历史上,甚至都是没有下划线的名字。我知道我遇到了问题其中名称CCD_ 8变为CCD_。看不到下划线,但是。。。然而,除了更改名称之外,你对此无能为力当冲突发生时。)

更普遍地说,下划线在某些字体中不会很好地显示,最好在符号的两端避开它们。

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

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

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

没有。它在任何地方都是保留的。再次阅读17.4.3.2.1:

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

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