Почему & quot; unsigned int ui = {-1}; & quot; сужающаяся ошибка преобразования?

Стандарт в п. 8.5.4 / 7 объясняет, что такое сужение конверсии является:

Сужающее преобразование — это неявное преобразование

— от типа с плавающей точкой к целочисленному типу, или

— от длинных двойных к двойным или плавающим, или от двойных к плавающим, кроме случаев, когда источник является константой
выражение и фактическое значение после преобразования находится в диапазоне значений, которые могут быть представлены
(даже если это не может быть представлено точно), или

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

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

Затем он запрещает такие преобразования в некоторых контекстах инициализации списка, давая
Примеры:

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

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 ошибок, проиллюстрированных примерами, сообщаются как таковые
лязг 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?

Что мне не хватает?

4

Решение

Конечно, -1 есть целочисленная константа, и, если она преобразуется в unsigned и обратно, все равно возвращает int -1?

Это не верно. Если вы конвертируете -1 в unsigned ты получаешь UINT_MAX, Это хорошо, потому что преобразование в неподписанные типы всегда определяется. Тем не мение, UINT_MAX не вписывается в int и преобразования в подписанные типы определяются стандартом только тогда, когда значение соответствует целевому типу.

6

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]