【问题标题】:Reserved names in the global namespace全局命名空间中的保留名称
【发布时间】:2012-03-28 23:07:18
【问题描述】:

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

在 cmets 中,有人告诉我 _Ints 标识符会调用未定义的行为,因为它是一个保留名称。但是,根据最近的标准草案,成员变量的名称查找使用以下规则:

3.4.3.1 类成员 [class.qual]

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

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

现在,问题来了:

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

【问题讨论】:

    标签: c++ token-name-resolution


    【解决方案1】:

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

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

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

    【讨论】:

    • "下划线在某些字体中的显示效果不是很好" - 1、l 和我在某些字体中看起来很相似,所以避免使用标识符中的那些?还是在阅读代码时避免使用那些字体?
    • 我同意史蒂夫的观点,下划线是编程生活中的一个事实,如果你的字体不能渲染它们,那么你就有问题了。 (我用的是比例字体,还是没有问题)
    • 我对此相当极端——如果可以避免的话,我不会阅读无法区分制表符和等量的空格。所以我对基本的文本可读性有相当高的标准。
    • @SteveJessop 仅因为一个使用小写字母 l 而另一个使用数字 1 而不同的符号不是一个好主意。至于下划线,它们用于分隔单词(它们类似于空格的事实并不是什么大问题),但区分_namename_name 几乎不比使用x1、@ 好987654328@ 或 xOx0
    【解决方案2】:

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

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

    【讨论】:

    • 我曾经表示“任何目的”而不是任何范围。为什么该规则在全局名称部分下。
    • @rerun 当然,“任何目的”包括在任何范围内声明变量。部分名称令人困惑,但重要的是部分的文本,它清楚地将保留标识符分为两种类型:保留用于任何用途,以及保留在全局命名空间中。
    【解决方案3】:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多