2011-11-11 91 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比這兩個標準的任務更寬鬆。