Сужение конверсии от неподписанного до двойного

static_assert(sizeof(unsigned) == 4, ":(");
static_assert(sizeof(double) == 8 ,":(");
unsigned u{42};
double x{u};

g++ 4.7.1 жалуется на этот код:

warning: narrowing conversion of 'u' from 'unsigned int' to 'double' inside { }

Почему это сужение конверсии? Не каждый unsigned прекрасно представлен как double?

3 ответа

Решение

Почему это сужение конверсии?

Потому что определение включает (с моим акцентом):

C++ 11 8.5.4 / 7 Сужающее преобразование - это неявное преобразование [...] из целочисленного типа [...] в тип с плавающей запятой, за исключением случаев, когда источником является константное выражение и фактическое значение после преобразование будет соответствовать целевому типу и даст исходное значение при преобразовании обратно в исходный тип.

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

Не каждый unsigned прекрасно представлен как double?

Это реализация определена. В общем случае 32-битный unsigned а также double с 52-битной мантиссой, это так; но некоторые реализации имеют больший unsigned и / или меньше double представления, поэтому код, который зависит от этого предположения, не является переносимым.

Предупреждение, которое вы получили, потому что вы инициализируете x непостоянным выражением

Ilyas-iMac:TestC++11 sandye51$ cat main.cpp                   
int main()
{
    static_assert(sizeof(unsigned) == 4, ":(");
    static_assert(sizeof(double) == 8 ,":(");
    constexpr unsigned u{42};
    double x{u};

    return 0;
}Ilyas-iMac:TestC++11 sandye51$ gcc -o main main.cpp -std=c++11
Ilyas-iMac:TestC++11 sandye51$ 

Как вы можете видеть код выше работает без каких-либо предупреждений или ошибок

(Давай попробуем:) double имеет ровно 52 бита значащих (двоичных) цифр (согласно стандарту ieee), тогда как unsigned int может иметь хорошие 64 бит в другой системе. Так актуально unsigned intШирина вашей системы может не иметь значения для этой проверки.

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