[英]Why is “unsigned int ui = {-1};” a narrowing conversion error?
§8.5.4 / 7中的標准解釋了縮小的轉換是:
縮小轉換是隱式轉換
—從浮點類型到整數類型,或者
—從long double到double或float,或者從double到float,除非源是一個常量表達式,並且轉換后的實際值在可以表示的值范圍內(即使不能精確表示),或者
—從整數類型或無作用域枚舉類型到浮點類型,除非源是常量表達式,並且轉換后的實際值將適合目標類型,並在轉換回原始類型時將產生原始值,要么
—從整數類型或無作用域枚舉類型到不能表示原始類型的所有值的整數類型,除非源是常量表達式,並且轉換后的實際值將適合目標類型並產生原始值當轉換回原始類型時。
然后,它在某些列表初始化上下文中禁止進行此類轉換,並提供示例:
[注意:如上所述,在列表初始化中,不允許在頂層進行此類轉換。 —尾注] [示例:
int x = 999; // x is not a constant expression
const int y = 999;
const int z = 99;
char c1 = x; // OK, though it might narrow (in this case, it does narrow)
char c2{x}; // error: might narrow
char c3{y}; // error: narrows (assuming char is 8 bits)
char c4{z}; // OK: no narrowing needed
unsigned char uc1 = {5}; // OK: no narrowing needed
unsigned char uc2 = {-1}; // error: narrows
unsigned int ui1 = {-1}; // error: narrows
signed int si1 =
{ (unsigned int)-1 }; // error: narrows
int ii = {2.0}; // error: narrows
float f1 { x }; // error: might narrow
float f2 { 7 }; // OK: 7 can be exactly represented as a float
int f(int);
int a[] =
{ 2, f(2), f(2.0) }; // OK: the double-to-int conversion is not at the top level
—結束示例]
示例所說明的所有7個錯誤都是由clang 3.2 / 3.3報告,帶有-std=c++11
,例如
error: non-constant-expression cannot be narrowed from type 'int' to 'char' in initializer list [-Wc++11-narrowing]
gcc 4.7.2 / 4.8.1均未將它們報告為錯誤,但是在每種情況下都給出類似的警告,例如
warning: narrowing conversion of ‘x’ from ‘int’ to ‘char’ inside { } [-Wnarrowing]
(因此,gcc似乎知道合規性要求,但默認情況下選擇容忍不合規。)
我不明白的是這個例子:
unsigned int ui1 = {-1}; // error: narrows
有資格作為一個例子。 (同樣地與對稱si1
示例)。顯然,通過該它可能有資格作為示例的唯一字是那些在上面給出的縮小轉換的定義中的第四和最后一個項目的; 但是,如果是這樣,那么為什么示例不能通過限定條件進行轉義, 除非源是一個常量表達式,並且轉換后的實際值將適合目標類型,並在轉換回原始類型時會產生原始值 ? 當然-1
有一個整數常數,如果將其轉換為unsigned
並返回,則仍會得出int -1
?
我想念什么?
當然-1有一個整數常量,如果將其轉換為無符號並返回,則仍會得出int -1?
錯了 如果將-1轉換為unsigned
則會得到UINT_MAX
。 這很好,因為始終定義為轉換為無符號類型。 但是, UINT_MAX
不適合int
,只有當值適合目標類型時,才由標准定義對有符號類型的轉換。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.