从文字缩小不会引起警告
Narrowing from literal doesn't cause warning
int a = 0; short b{a}; short c{0};
编译器对 short b{a}
发出警告。我可以理解这一点,因为 int
缩小为 short
。
但是,它没有向 short c{0}
发出警告,这对我来说很奇怪。我记得对于文字整数,0
的类型至少应该是 int
。所以从 int
缩小到 short
就发生在这里。为什么编译器不给出警告?
对于 short c{0};
,narrowing conversion 不会出现。因为 0
是一个常量表达式,可以精确地存储在 short
.
(强调我的)
list-initialization limits the allowed implicit conversions by prohibiting the following:
...
conversion from integer or unscoped enumeration type to integer type that cannot represent all values of the original, except where source is a constant expression whose value can be stored exactly in the target type
来自标准的相关解释和例子,$8.6.4/7 List-initialization
[dcl.init.list]:
(强调我的)
A narrowing conversion is an implicit conversion
...
from an integer type or unscoped enumeration type to an integer type that cannot represent all the values of the original type, except
where the source is a constant expression whose value after integral
promotions will fit into the target type.
[ Note: As indicated above, such conversions are not allowed at the
top level in list-initializations. — end note ] [ Example:
// ...
const int z = 99;
// ...
char c4{z}; // OK: no narrowing needed
unsigned char uc1 = {5}; // OK: no narrowing needed
// ...
float f2 { 7 }; // OK: 7 can be exactly represented as a float
// ...
— end example ]
int a = 0; short b{a}; short c{0};
编译器对 short b{a}
发出警告。我可以理解这一点,因为 int
缩小为 short
。
但是,它没有向 short c{0}
发出警告,这对我来说很奇怪。我记得对于文字整数,0
的类型至少应该是 int
。所以从 int
缩小到 short
就发生在这里。为什么编译器不给出警告?
对于 short c{0};
,narrowing conversion 不会出现。因为 0
是一个常量表达式,可以精确地存储在 short
.
(强调我的)
list-initialization limits the allowed implicit conversions by prohibiting the following:
...
conversion from integer or unscoped enumeration type to integer type that cannot represent all values of the original, except where source is a constant expression whose value can be stored exactly in the target type
来自标准的相关解释和例子,$8.6.4/7 List-initialization [dcl.init.list]:
(强调我的)
A narrowing conversion is an implicit conversion
...
from an integer type or unscoped enumeration type to an integer type that cannot represent all the values of the original type, except where the source is a constant expression whose value after integral promotions will fit into the target type.
[ Note: As indicated above, such conversions are not allowed at the top level in list-initializations. — end note ] [ Example:
// ... const int z = 99; // ... char c4{z}; // OK: no narrowing needed unsigned char uc1 = {5}; // OK: no narrowing needed // ... float f2 { 7 }; // OK: 7 can be exactly represented as a float // ...
— end example ]