clang vs gcc中空结构的默认初始值设定项

时间:2017-02-15 13:46:25

标签: c++ g++ c++14 clang++

以下代码使用GCC和某些版本的Clang编译某些版本(请参阅下面的版本)。

struct my_struct {};

int main(int argc, char** argv) {
  const my_struct my_object;
  return 0;
};

编译:{{1​​}}和g++ clang_error.cpp。我在 4.8.4 和clang ++在3.6.0时使用g ++。

错误消息是:

clang++ clang_error.cpp

受影响的版本

使用 Compiler Explorer here,我可以看到GCC高达4.5.4受到影响。 Clang受到的影响高达3.9.0。

问题

我的问题是: C ++标准对此有何看法?理想情况下,我关心的是C ++ 14,但我并不挑剔。

以上示例代码是否符合标准?

到目前为止我发现的

我在C ++ 14的Draft N3797中找到了以下内容。

  

§7.1.6.1cv-qualifiers [dcl.type.cv]
  2 [注意:声明变量const可以影响其链接(7.1.1)及其在常量表达式(5.19)中的可用性。   如8.5中所述,const限定类型的对象或子对象的定义必须指定初始化器   或接受默认初始化。 - 结束注释]

     

§8.5   7默认初始化T类型的对象意味着:
   - 如果T是(可能是cv限定的)类类型(第9节),则调用T的默认构造函数(12.1)(和   如果T没有默认构造函数,则初始化是错误的,或者重载解析(13.3)导致   模糊性或在初始化上下文中删除或无法访问的函数中;;    - 如果T是数组类型,则每个元素都是默认初始化的;
   - 否则,不执行初始化。

1 个答案:

答案 0 :(得分:4)

  

C ++标准对此有何看法?

     

以上示例代码是否符合标准?

在C ++ 14中,它不符合要求:

  

n4431(2015)标准草案[dcl.init] / 7:

     

如果程序要求对const限定类型的对象进行默认初始化   Ť   ,   Ť   应为班级类型   使用用户提供的默认构造函数。

my_struct没有用户提供的默认构造函数,因此您不应默认初始化。

但是,一些较新的编译器似乎选择放宽规则,可能是因为它受到缺陷报告的影响:DR 253

即将推出的标准改变了措辞:

  

Current(2017)标准草案[dcl.init] / 7

     

如果T的默认初始化将调用用户提供的T构造函数(不是从基类继承)或者

,则类类型T是const-default-constructible      

(7.4)T的每个直接非变量非静态数据成员M都有一个默认成员初始化器,或者,如果M是类X(或其数组),则X是const-default-constructible,

     

(7.5)如果T是与至少一个非静态数据成员的并集,则只有一个变体成员具有默认成员初始值设定项,

     

(7.6)如果T不是联合,对于每个具有至少一个非静态数据成员(如果有)的匿名联合成员,只有一个非静态数据成员具有默认成员初始化程序,并且

     

(7.7)每个可能构造的T的基类都是const-default-constructible。

     

如果程序要求对const限定类型T的对象进行默认初始化,则T应为const-default-constructible类类型或其数组。

措辞对我来说有点模棱两可,但我认为由于my_struct没有违反7.4的成员(并且不是工会,所以7.5不适用,没有工会成员所以7.6不适用并且没有基础,因此7.7不适用),它是const-default-constructible,因此该示例将是符合的。