decltype和类成员名称之间的交互阴影外部名称

jac*_*acg 8 c++ gcc scope decltype language-lawyer

这段代码

int clash;

struct Foo {
  decltype(clash) clash;
};
Run Code Online (Sandbox Code Playgroud)

在clang上静默编译,但无法在gcc上编译给出错误

错误:'int Foo :: clash'的声明[-fpermissive]

错误:从'int clash'改变'clash'的含义[-fpermissive]

看起来错误需要2个成分:

  1. 阴影必须由类成员完成(如果它是函数的本地范围则没有问题).

  2. 在声明[阴影名称]之前,必须在阴影范围内使用decltype([阴影名称]).

我的问题是双重的:

  1. gcc是否有理由拒绝此代码?
  2. 在标准中它在哪里这样说?

Sha*_*our 10

gcc是正确的程序是不正确的,虽然这种特殊的违规行为不需要诊断,所以clang不必提供一个.

如果我们看一下C++ 11标准(最接近的草案将是N3337)部分3.3.7 类范围,它说:

在类S中使用的名称N应在其上下文中引用相同的声明,并在完成的S范围内重新评估.违反此规则不需要诊断.

而下一条规则说:

如果类中的重新排序成员声明在(1)和(2)下产生备用有效程序,则程序格式错误,不需要诊断.

有意义的是,我们希望防止重新排序类中的声明给出不同程序的情况.很遗憾这两条规则是否多余.

该部分还提供以下示例:

enum { i = 1 };

class X {
  char v[i]; // error: i refers to ::i
             // but when reevaluated is X::i
  int f() { return sizeof(c); } // OK: X::c
  char c;
  enum { i = 2 };
};
Run Code Online (Sandbox Code Playgroud)

如果我们尝试这个例子gcc(看到它的实时),我们会得到一个与你的代码产生的几乎相同的错误:

 error: declaration of 'i' [-fpermissive]
 enum { i = 2 };
          ^

 error: changes meaning of 'i' from '<anonymous enum> i' [-fpermissive]
 enum { i = 1 };
Run Code Online (Sandbox Code Playgroud)

  • 草稿"意义不大"不是......*完全*真实.他们的完整名称是"标准**工作**草案",因此它们比"仅仅草案"更多.看看[这个问题](http://stackoverflow.com/questions/14184203/changes-between-c-standard-working-drafts),很明显他们会逐渐完善. (4认同)