从文字缩小不会引起警告

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 ]