2017-05-04 82 views
12
int main() 
{ 
    short n1 = 8ll; // no warning 

    // warning C4305: 'initializing': truncation from '__int64' to 'short' 
    // warning C4309: 'initializing': truncation of constant value 
    short n2 = 88888ll; 
} 

我的編譯器的Visual Studio 2017C++是否允許將任何整數文字隱式轉換爲短整型?

根據cppref

的類型整數文字的是其中值 可以適合,從類型列表中的第一類型的取決於哪個數字庫 以及使用了哪個整數後綴。

帶後綴ll的整數字面值應爲long long int;所以short n1 = 8ll應該會觸發像short n2 = 88888ll這樣的警告。

C++是否允許任何整數文字被隱式轉換爲short int如果它足夠小?

+6

「應該觸發警告」 - 編譯器對於警告非常自由。當標準表示需要診斷時,他們可能會發出警告,但他們也可能在標準保持沉默的情況下給予警告。編譯器可以很聰明。它知道它自己的限制,所以它可以給出'88888LL'的警告,而不是'8LL'。 – MSalters

+6

您可以使用大括號來禁用隱式轉換,例如'short n2 = {88888LL};'(此功能是在C++ 11中添加的) –

+4

@ M.M:支持的初始化器語法禁止**縮小**轉換。隱含的擴展轉換仍然發生。 –

回答

21

該標準允許在任何兩個整數類型之間進行隱式轉換,而不管它們的值如何。

編譯器警告與代碼合法無關;編譯器只是在你的代碼可能沒有做到你想要的時候提醒你。

在您的具體情況下,n1應爲8,n2將具有實現定義的值。這兩項任務都是合法的C++,但後者可能不是您想要的。


相關standardese:

的整數類型的prvalue可以被轉換成另一種整數類型的prvalue。枚舉類型可以轉換爲整數類型的prvalue。
如果目標類型是無符號的,則結果值是與源 整數相同的最小無符號整數(模2 2 n其中n是用於表示無符號類型的位數)。 [注意:在兩個 補碼錶示中,此轉換是概念性的,並且位模式沒有變化(如果 不是截斷)。 - 結束註釋]
如果目標類型是帶符號的,如果它可以用目標類型表示(並且位域寬度爲 ),則值不變。否則,該值是實現定義的。

4.7 /在N4141

1-3
4

是,整數可以隱式轉換。這些是從C++標準草案N4296的規則:

4.7積分轉換
的整數類型的prvalue可以被轉換成的另一 整數類型prvalue。非範型枚舉類型的前值可以是 轉換爲整數類型的prvalue。
如果目的地類型 是無符號的,所得到的值是至少無符號整數 全等到源整數(模2 Ñ其中n是用於表示無符號類型 比特的數量)。
[注意:在兩個 補碼錶示中,此轉換是概念性的,並且存在位模式(如果沒有截斷)沒有變化。 - 結束]
如果目的地類型是有符號的,如果 可以在目的地類型中表示,則值不變;否則,值爲 實現定義。
如果目標類型是bool,請參閱4.12。 如果源類型爲bool,則將值false轉換爲零,並且將值true轉換爲1。
允許作爲 積分促銷的轉換被排除在積分轉換集之外。

相關問題