【问题标题】:The snippet shown below compiles in Coliru and Ideone, but according to iso § 8.5 p6 it shouldn't, or am I missing something?下面显示的代码片段在 Coliru 和 Ideone 中编译,但根据 iso § 8.5 p6 它不应该,或者我错过了什么?
【发布时间】:2014-01-03 17:48:31
【问题描述】:

从 C++11 标准 § 8.5 p6 我们有:

如果一个程序调用一个对象的默认初始化 const 限定类型 T,T 应是具有用户提供的类类型 默认构造函数。

以下代码应该编译。但在 Coliru 和 Ideone 中确实如此。

class A{};

int main() {
    const A a;
}

编辑:

在试图了解这里发生了什么时,我最终得到了以下代码,它可以编译(至少它符合标准,因为A 有一个用户提供的构造函数)。但随后我想到了以下问题:哪个标准子句确实保证a.b.j 初始化为0(参见Ideone 中的代码),下面?

#include <iostream>
struct B { int j; B(){ std::cout << "B()" << '\n'; } };
struct A
{
    struct B b;
    int i;

    public:
    A(): i(1) { std::cout << "A()" << '\n'; }

};  

int main() {
    const A a;
    std::cout << a.b.j << '\n';
    std::cout << a.i << '\n';
}

编辑1:

很抱歉上面的编辑,但我仍然不使用 Unix。上周Dietmar Kühl 让我注意到"Most UNIXes start off with zero initialized pages" 的事实。因此,正如我所想的那样,由于初始化, a.b.j 不是 0。事实上,我刚刚用 VS2010 编译了代码,a.b.j 的结果正如预期的那样是一个未初始化的值。因此,Edit中的问题应该被忽略。

但我很想知道 clang++ 或 g++ 是否也会显示第二个 sn-p 错误。谢谢。

【问题讨论】:

  • clang++3.4 错误:const 类型“const A”的对象的默认初始化需要用户提供的默认构造函数
  • @DyP 是的,我也是。而 g++ 说:error: uninitialized const ‘a’
  • 请注意,一旦添加数据成员,g++ 就会报错:main.cpp:7:13: error: uninitialized const 'a' [-fpermissive] main.cpp:1:8: note: 'const struct A' has no user-provided default constructor
  • @TemplateRex 我不同意。另一个问题询问该规则的原因。这个问题询问编译器是否以及为什么不遵循空类的规则。

标签: c++ c++11 language-lawyer default-constructor


【解决方案1】:

研究了初始化和聚合的规则后,我认为你是对的——在技术上是错误的。

您的编译器正在走捷径,因为没有成员,因此实际上不需要初始化。 (有趣的是,the ancient GCC 4.1.2 rejects the program。)

很遗憾,我没有什么可引用的,因为在这种情况下根本没有规则覆盖 [C++11: 8.5/6]

至于为什么标准不允许这样做,为什么要这样做?空类几乎没有用处,我看不出有理由为这种极端情况积极地为更广泛、更有用的rule 编写豁免。

【讨论】:

    【解决方案2】:

    考虑到第 7.1.6.1 节第 #2 节中的注释 cv-qualifiers 写在哪里:

    2 [注意:声明变量 const 会影响其链接 (7.1.1) 及其在常量表达式中的可用性(5.19)。如 8.5 中所述, const 限定类型的对象或子对象的定义必须 指定一个初始化器或服从默认初始化。 -结尾 注意]

    似乎编译器确实有点奇怪。

    虽然如果您要添加数据成员,代码将不会在 ideone 中编译,但至少会在 MS VC++ 2010 中编译。 在您提供的报价中,没有提及数据成员。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-03
      相关资源
      最近更新 更多