2013-06-20 50 views
7

我偶然發現了一個令人困惑的情況,我發現了一個明顯的縮小轉換,但我感到失望的是編譯器(gcc-4.7.2)沒有發出警告,儘管標記爲-Wall -Wnarrowing -pedantic。請看下面的程序:用圓括號初始化時沒有縮小的警告

struct A { 
    int m; 
    A(int m) : m(m) {}; 
}; 

int main() { 
    unsigned long v = 0; 
    A a1(v); // narrowing, but no warning (should this not cause a warning?) 
    A a2{v}; // narrowing, warning raised (expected) 
} 

a1初始化似乎沒有那麼多飛從編譯器窺視。爲了確保我不會精神失常,我試圖用相同的方式初始化a1,但用大括號代替parens。正如預期的那樣,編譯器警告在第二種情況下縮小範圍。

要清楚:我沒有問初始化列表中縮小轉換的合法性。我知道這是不合法的 - a2的捲曲支撐初始化僅僅是一種健全檢查。 我的問題與初始化列表無關。這不是一個重複的問題。

編譯器不應該警告我縮小初始化a1

+0

'a1'的構造函數可以做一個隱式轉換,而'a2'則不能。你爲什麼認爲他們應該是一樣的? –

+1

如果添加'-Wconversion'標誌怎麼辦? –

+0

這不是重複的。我已經意識到縮小初始化列表中的轉換是非法的。我用括號詢問初始化。 –

回答

2

Wsign-conversion將生成該行代碼的警告 - -Wconversion不會當unsigned longint具有相同的尺寸(這是真的在很多平臺上,甚至有些64位平臺)。對於C代碼,-Wconversion將隱式啓用-Wsign-conversion,但由於某些原因,C++不會發生這種情況。

如果更改的v類型long long-Wconversion本身會產生一個警告(假設int是32位)。

+0

非常感謝您的洞察力。我很高興初始化程序列表語義對於轉換非常具體 - 這可能是我開始使用'{}'的一個很好的理由,無論我需要哪種代碼最便於移植,因此編譯器可以在實際目標之前捕獲轉換缺陷一個新的平臺。 –