1

int a = 0; short b{a}; short c{0};Сужение из буквальным не вызывает предупреждения

Компилятор дает Уоринг для short b{a}. Я могу это понять, потому что int сужается до short.

Однако, это не дает предупреждение short c{0}, что для меня странно. Я помню, что для буквенных целых чисел тип 0 должен составлять не менее int. Таким образом, сужение от int до short происходит здесь. Почему компилятор не дает предупреждение?

ответ

5

Для short c{0};, narrowing conversion не возникает. Потому что 0 является постоянным выражением и может храниться точно в short.

(курсив мой)

список инициализация ограничивает допустимые неявные преобразования, запрещая следующее:

  • ...

  • преобразования из целого или незаданного типа перечисления в целочисленный тип, который не может представлять все значения оригинала, , за исключением случаев, когда источником является постоянное выражение, значение которого может быть сохранено точно в целевой тип

Соответствующие пояснения и примеры из стандарта, $8.6.4/7 List-initialization [dcl.init.list]:

(курсив мой)

сужающее преобразование неявное преобразование

  • ...

  • от целого типа или незаданного типа перечисления для целочисленного типа, которые не могут представлять все значения исходного типа, исключения , где источник является постоянным выражением, значение которого после интегральных акции поместит в целевом тип.

[Примечание: Как указано выше, такие преобразования не допускается на верхнем уровне в списке-инициализациях. - конец примечание] [Пример:

// ... 
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 
// ... 

- конец пример]

+0

вы думаете, "после того, как неотъемлемые акции" ненужный? – FunkyBaby

+0

@FunkyBaby Я думаю, что это просто означает технически, константа будет сначала повышаться, а затем повышаемое значение будет проверено, может ли оно вписаться в целевой тип. – songyuanyao