Определенные реализацией сужающие преобразования?

C++11 формализовал понятие сужающегося преобразования и запретил использовать его на верхнем уровне при инициализации списка.

Мне интересно, если, учитывая два типа T а также U, это может быть определено реализацией, является ли преобразование из T в U сужается. Согласно моему прочтению стандарта, это так. Вот мои рассуждения:

  • Согласно пункту 7 dcl.init.list (8.5.4), один из способов сужения преобразования - это неявное преобразование "целочисленного типа или перечислимого типа с незаданной областью в целочисленный тип, который не может представлять все значения оригинала. тип".
  • Рассмотрим неявное преобразование из unsigned int в long,
  • Что касается относительных размеров int а также long, C++ требует только, чтобы sizeof(int) <= sizeof(long),
  • Рассмотрим реализацию А, где sizeof(int) == sizeof(long), На этой реализации, long не может представлять все значения unsigned int, поэтому конверсия будет сужаться.
  • Рассмотрим реализацию B, где sizeof(int) < sizeof(long), На этой реализации, long может представлять все значения unsigned int, поэтому конверсия не будет сужаться.

Правильно ли я в своем анализе, что это может быть определено реализацией, сужается ли конверсия? Это желательно?

2 ответа

Я бы действительно предпочел, чтобы "сужающее преобразование" было определено для самих типов. Таким образом, чтобы int i{long(non_constant_expression)} никогда не разрешается компилировать. Причина проста: либо вам не нужен большой радиус действия, вам следует использовать int во-первых, или вы действительно хотите "вырезать", что кажется мне достаточно редким случаем, когда требуется явное преобразование типа или приведение. Чтобы ответить на первый вопрос: это определение реализации.

Но, если честно, я почти никогда не использую этот сырой тип, просто size_t, int32_t, uint16_t и т.д., и это решает проблему автоматически. (uint16_t {uint8_t()} всегда сужается, uint16_t{uint16_t()} никогда.) Нужно только вдумчиво преобразовать size_t во что-то другое, но это всегда так.

В моем случае для этого фрагмента кода:char *pointer = strchr(s1, s2[I]); int start = pointer - s1;Это помогло изменитьintтип данных дляlong:long start = pointer - s1;

«Компилятор не может определить, насколько велико или мало значение для определенного типа данных; следовательно, компилятор не может определить, помещается ли указанное значение в новое поле, которому вы его присваиваете. Если вы уверены, что нет переполнения, явно введите значение, чтобы избежать предупреждения». - источник: https://www.ibm.com/docs/en/ztpf/2020?topic=warnings-narrowing-conversion .

Другие вопросы по тегам