2012-10-13 67 views
6

任何人都可以請我解釋一下,爲什麼編譯器允許初始化內置類型的變量,如果初始化器可能會導致信息丟失?爲什麼編譯器允許縮小轉換範圍

例如C++ Primer,第5版說,編譯器不會讓我們列出初始化變量的內置類型,如果初始化器可能導致信息丟失。

但我的編譯器GCC 4.7.1 v在成功地將下面的代碼初始化的變量a

long double ld = 3.1415926536; 
int a{ld}; 

只是有警告:從「長雙」到「廉政」內縮小「LD」的轉換{ } [ - 差點]。

+2

我會說這本書是錯誤的。 C和C++與這種東西非常疏忽...... –

+0

@MatthieuM。 C++ 11不是。 – rubenvb

+0

** n3337 ** ** 4.9/1 [conv.fpint] ** *浮點類型的前值可以轉換爲整數類型的前值。轉換截斷;也就是說,小數部分被丟棄。如果在目標類型中不能表示被截斷的值,那麼行爲是不確定的*因此,轉換是可能的並且在標準中實際定義,不清楚的是它是否被允許*這裏*,並且我還沒有發現任何關於。 –

回答

10

之一初始化列表的特徵在於,收縮轉換是不允許的。但是,語言定義並不區分警告和錯誤;當代碼格式不正確時,它需要「診斷」,它被定義爲來自一組實現定義消息的任何消息。警告符合這個要求。這是非標準擴展的機制:發佈了警告,編譯器可以自由地做任何事情,包括根據特定於實現的規則編譯內容。

2

您可以設置編譯器標誌將所有警告標記爲錯誤。在這種情況下,只有它會阻止你這樣做。否則它只會是一個警告。

0

這個問題最近出現了。用gcc-4.7一個命令行開關接通所需的行爲:

g++ -Werror=narrowing ... 
+0

這不是C++ 11的變化嗎?我認爲在C++ 11之前允許縮小轉換範圍,但是根據C++ 11中的通用初始化語法禁止轉換。 – rubenvb

+2

@rubenvb - 它不會改變任何東西從C + + 03;它引入了**新語法**用於初始化,具有不同的規則(不縮小轉換);使用其他形式的初始化的代碼不受限於縮小轉換的限制。 –

+2

@Pete使用braced-init-list(C++ 03中可能使用不同的名稱)初始化數組不允許縮小C++ 11中的轉換次數,這是一個重大改變。 – rubenvb

相關問題