为什么gcc允许一个没有用户声明的默认构造函数的const对象,而不允许clang

Why does gcc allow a const object without a user-declared default constructor but not clang?

本文关键字:对象 const 构造函数 clang 不允许 默认 为什么 许一个 声明 用户 gcc      更新时间:2023-10-16

最近为什么const对象需要用户提供的默认构造函数?被标记为"为什么C++需要用户提供的默认构造函数来默认构造const对象?"的副本?。我使用coliru和rexter来测试各种版本的gcc(g++-4.7、g++-4.8、g++-4.9)和clang(3.4和3.5),看看这种行为是否在较新版本的编译器中引入。这里我们有两个测试用例,分别来自两个问题:

class A {
public:
    void f() {}
};
int main()
{
    A a;       // OK
    const A b; // ERROR
    a.f();
    return 0;
}

和:

struct B{
  B():x(42){}
  int doSomeStuff() const{return x;}
  int x;
};
struct A{
  A(){}//other than "because the standard says so", why is this line required?
  B b;//not required for this example, just to illustrate
      //how this situation isn't totally useless
};
int main(){
  const A a;
}

叮当错误与:

 error: default initialization of an object of const type 'const A' requires a user-provided default constructor
  A const a;
          ^

预期但不是gcc,MSVC也不是。我想我可能快疯了,因为标准报价清楚地写着:

§8.5

6默认初始化T类型的对象意味着:

--如果T是(可能是cv限定的)类类型(第9条),则默认构造函数对于T被调用(并且如果T没有可访问的默认构造函数);

[…]

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

11如果没有为对象指定初始值设定项,则该对象为默认初始化;[…]

第二个问题中出现的非POD语言似乎在n3337中丢失了,所以也许我丢失了一些可能已经改变的东西。这是一个错误、重复还是我遗漏了什么?

规范目前需要用户提供的默认构造函数,但GCC似乎正在实现基于DR 253的更改,该更改表示,如果所有子对象都将在没有用户提供的缺省构造函数的情况下初始化,则不需要用户提供的缺省构造函数。

此更改仅为草案状态,尚未被接受,也不属于标准的一部分。所以我认为这是GCC开发人员想要的行为,但我不确定这是否是一个一致的扩展。

以下是对第一个示例的更改,它导致GCC产生错误:

class A {
public:
    void f() {}
    int i;
};
int main()
{
    A a;       // OK
    const A b; // ERROR
    a.f();
    return 0;
}

请注意,gcc使用-fpermission标志将错误降级为警告。

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=42844