未初始化的常量

时间:2011-11-11 10:30:17

标签: c++ visual-c++ g++ const default-constructor

这与当前的MSVC编译器编译完全相同:

struct Foo
{
} const foo;

但是,它无法使用当前的g ++编译器进行编译:

error: uninitialized const 'foo' [-fpermissive]
note: 'const struct Foo' has no user-provided default constructor

如果我自己提供默认构造函数,它可以工作:

struct Foo
{
    Foo() {}
} const foo;

这是MSVC的另一种情况是过于宽松,还是g ++过于严格?

4 个答案:

答案 0 :(得分:15)

C ++ 03标准:

8.5 [dcl.init]第9段

  

如果没有为对象指定初始化程序,并且该对象是(可能是cv限定的)非POD类类型(或其数组),则该对象应默认初始化;如果对象是const限定类型,则底层类类型应具有用户声明的默认构造函数。

从上面看,gcc中的错误似乎完全有效。

答案 1 :(得分:5)

  

[2003: 8.5/9]: 如果没有为对象指定初始值设定项,则为   object是(可能是cv限定的)非POD类类型(或数组   其中,该对象应默认初始化;如果对象是   const-qualified类型,底层类类型应具有   用户声明的默认构造函数。否则,如果没有初始化器   为非静态对象,对象及其子对象指定,如果   任何,具有不确定的初始值; 如果对象或任何   它的子对象属于const限定类型,程序格式不正确。

  

[n3290: 8.5/11]: 如果没有为对象指定初始化程序,则默认初始化对象; 如果没有初始化   执行时,具有自动或动态存储持续时间的对象具有   不确定的价值。 [注意:具有静态或线程存储的对象   持续时间为零初始化,见3.6.2._ -end note_]

     

[n3290: 8.5/6]:默认初始化T类型的对象意味着:

     
      
  • 如果T是(可能是cv限定的)类类型(第9条),则调用T的默认构造函数(如果T没有,则初始化不正确可访问的默认构造函数);
  •   
  • 如果T是数组类型,则每个元素都是默认初始化的;
  •   
  • 否则,不执行初始化。
  •   
     

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

所以MSVC在这里比两个标准要求更宽松。

答案 2 :(得分:2)

我不知道该标准的确切措辞,但g ++中的错误似乎比不说任何内容的选项更明智。考虑一下:

struct X {
   int value;
};
const X constant; // constant.value is undefined

不是在用户提供的默认构造函数的情况下(即使它什么都不做),编译器将调用该构造函数,并且该对象将初始化(通过初始化的任何定义

答案 3 :(得分:0)

C ++ 17更新

C ++ 17在const限定的类类型具有默认构造函数的要求上增加了一些细微差别。现在,该标准定义了“ const-default-constructable”概念:

  

7要 default-initialize 类型为T的对象的意思是:

  (7.1)—如果 T 是(可能是cv限定的)类类型,则考虑构造函数。列举了适用的构造函数,并通过重载决议为 initializer ()选择了最佳的构造函数。如此选择的构造函数被调用,并带有一个空的参数列表,以初始化   对象。
  (7.2)—如果 T 是数组类型,则每个元素都将默认初始化。
  (7.3)—否则,不执行初始化。

  如果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可构造的类类型或其数组。 / p>