2011-11-11 87 views
14

这将编译与当前的MSVC编译器完美的罚款:未初始化的常量

struct Foo 
{ 
} const foo; 

但是,它未能与目前克至编译++编译器:

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

如果我提供一个默认的构造函数自己,它作品:

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

这是MSVC的另一种情况是过于宽容,或者g ++太严格吗?

+0

伟大的问题先生溢出。 –

+0

Duplicates:http://stackoverflow.com/questions/5335836/why-a-const-object-of-an-empty-class-cant-be-created http://stackoverflow.com/questions/7411515/why- do-c-require-a-user-provided-default-constructor-to-default-construct-a等等。 – GManNickG

+0

我无法在GCC 4.6.1上使用任何方言选项重现此操作。它只适用于我安装成员变量(如'int a;'),并且错误更加准确:''const struct Foo'没有用户提供的默认构造函数,隐式定义的构造函数不会初始化'int Foo :: a'' –

回答

13

的C++ 03标准:

8.5 [dcl.init]段落9

如果对象没有指定初始化,并且该对象是(可能CV的 - 限定的)非POD类类型(或其数组),对象应该被默认初始化;如果该对象属于const限定类型,则基础类类型应具有用户声明的默认构造函数。

从上面的错误gcc似乎是完全有效的。

+7

+1先生我是一个哈希表的标准:-) –

1

我不知道该标准的确切用词,但g ++中的错误看起来比不说任何话的选项更明智。试想一下:

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

不在用户提供默认的构造函数(即使它什么都不做),编译器会调用构造函数和对象将是初始化(通过任何的定义初始化你的情况下,已经在你的构造函数中实现)。

3

[2003: 8.5/9]:如果对象没有指定初始化,并且 目的是(可能CV修饰)非POD类类型(或阵列 物)的,对象应是缺省初始化;如果对象为const限定类型 ,则基础类类型应具有用户声明的默认构造函数 。否则,如果没有初始化程序是为非静态对象指定的 ,则该对象及其子对象(如果有 任何)具有不确定的初始值; 如果对象或其任何子对象属于const限定类型,则该程序不合格。

和:

[n3290: 8.5/11]:如果对象没有指定初始化,对象是缺省初始化;如果未执行初始化,则执行 ,具有自动或动态存储持续时间的对象具有不确定值 。 [备注:静态或线程储存的对象 持续时间是零初始化的,见3.6.2。_末端note_]

[n3290: 8.5/6]:要默认初始化T类型的对象是指:

  • 如果T是一个(可能CV修饰)类型(第9节),默认构造因为T被调用(并且如果T没有可访问的默认构造函数,则初始化不合格);
  • 如果T是一个数组类型,每个元素都是默认初始化的;
  • 否则,不执行初始化。

如果程序要求一个常量限定类型T的对象的默认的初始化,T应是一个类的类型与用户提供的默认的构造。

所以MSVC比这两个标准的任务更宽松。