【问题标题】:"extra qualification" errors. How warranted by the Standard?“额外资格”错误。标准如何保证?
【发布时间】:2013-08-03 09:18:49
【问题描述】:

This similar ill-fated question 在关闭之前得到了 cmets 和简短的答案,大意是:因为那是 语言是如何定义的。在这里,我要求提供证据 如此定义的 C++ 标准。

gcc 4.8.1 和 clang 3.3 类似,具有默认诊断选项或更严格, 给出额外限定显式限定的错误 代码如:

struct x
{
    int x::i; // Error: gcc/clang: "extra"
};

int ::y; // Error: gcc: "explicit", clang: "extra"

gcc 自 v4.1 起已诊断出此类错误。但是流行的编译器不是 一致同意这些错误。 MSVC++ 2012(十一月 CTP) 在int ::y; 处出现错误,但即使使用/Wall,也根本不提供诊断 int x::i; - 命运多舛的提问者提出的那种情况 - 并且这种差异表明 MS 编译器作者深思熟虑。

如果存在这些错误,标准如何保证?对 C++11 的引用 标准就足够了。

答案可能是“它们遵循语法”。在这种情况下, 请尝试展示它们如何遵循语法并随意使用 标准的语法分类。我有一份副本,我会重新阅读 理解解释。

【问题讨论】:

  • 我相信this 是骗子。这是非法的(根据我在欺骗中的回答中的引用),但在 C++1y 中是允许的(参见 litb 回答中的链接)。
  • 我同意我欺骗了链接的Q,它非常有帮助。
  • @jrok 这是一个不同的问题。此问题中显示的内容在 C++14 中仍然无效。

标签: c++ c++11 compiler-errors standards qualified-name


【解决方案1】:

C++ 中的限定名称始终必须引用先前声明的名称。这在第 8.3 节和第 3.4.3.2 节中有规定。

您不能首先通过使用限定名称来声明变量或成员 - 最终会出现类似“无法解析标识符”的编译器错误。此类限定符旨在用于重新声明。因此要求这些名称必须找到先前声明的实体。

【讨论】:

  • @Johannes Schaub - litb 是的,它是 8.3,请修改,我会接受。
【解决方案2】:

struct x 的定义中允许x::i 是Microsoft 编译器中的一个错误。 MSVC 前端有几个这样的错误,并且已报告给 Microsoft,但它们在没有得到修复的情况下关闭(请参阅此处报告的类似但不同的错误:https://connect.microsoft.com/VisualStudio/feedback/details/783433/c-compiler-accepts-explicit-constructor-call#detailshttps://connect.microsoft.com/VisualStudio/feedback/details/794504/keyword-struct-before-constructor-name)。

它无效的原因是因为您都试图声明一个变量int i 并使用x::i 提供一个范围。变量的范围是由它声明的where决定的,所以试图用一个范围规范来声明一些东西就是试图在其他地方声明它,这是无效的。

【讨论】:

  • 我在“要求 C++ 标准中的证据”。由 jrok 链接的 Q. 提供了它。尽管示例中的范围解析是多余的,而且实际上 C++11 是非法的,但您自己的理由是不正确的。变量的范围由声明它的位置决定,但范围解析运算符只是尝试指定其左侧的操作数声明的范围,对于x::i,范围为@987654330全局命名空间中的@ 或::y 不是“其他地方”,而是假定声明的范围。
  • 我试图解释您不能将范围分辨率与定义混合在一起,因为它们不兼容。
  • 只有在标准规定时它们才不兼容。在我编写 C++ 的大部分时间里,这样的定义是合法且司空见惯的。然后它们变得非法,并且随着 C++14 的出现,它们似乎将再次变得合法。 fourmilab.ch/fourmilog/archives/2006-05/000699.html
  • 是的,@jrok 的引用 stackoverflow.com/questions/17958497/… 没有在 class x 中显示标准禁止 int x::i; 吗?你引用了一个 7 岁的咆哮,它没有描述这是如何 - 不是 - 不会是有效的,它只是抱怨多年前的 gcc 实施。我错过了什么吗?
  • 您错过了我(两次)要求从标准中获得证据的事实,而是给出了您自己的错误先验理由。你没有回答问题。链接的旧咆哮是随机选择的证据,证明违反先验基本原理的代码一直以某种方式编写和编译,直到被标准禁止。这就是我要说的,我害怕。如果您仍然认为您的答案还不错,请对其进行任意编辑,这样我就可以删除我的反对票。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-17
  • 2016-09-10
  • 1970-01-01
  • 2022-11-10
  • 2011-10-07
  • 1970-01-01
  • 2013-09-15
相关资源
最近更新 更多