42
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吗?

4

3 回答 3

45

为什么这是一个缩小转换?

因为定义包括(我强调):

C++11 8.5.4/7窄化转换是从整数类型 [...] 到浮点类型的隐式转换 [...],但源是常量表达式和后面的实际值除外转换将适合目标类型,并在转换回原始类型时生成原始值。

u不是常量表达式,因此无论源类型的所有可能值是否都可以在目标类型中表示,这都是一种缩小转换。

不是每个都可以unsigned完美地表示为double吗?

那是定义的实现。在 32 位unsigneddouble52 位尾数的常见情况下,就是这样;但是某些实现具有更大unsigned和/或更小的double表示形式,因此依赖于该假设的代码不可移植。

于 2012-07-17T11:02:12.570 回答
4

您收到的警告是因为您使用非常量表达式初始化 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$ 

如您所见,上面的代码可以正常工作,没有任何警告或错误

于 2012-07-17T11:01:37.467 回答
1

(让我们试试看:)double正好有 52 位有效(二进制)数字(根据 ieee 标准),而unsigned int在其他一些系统上可能有很好的 64 位。因此unsigned int,您系统上的实际宽度可能对此检查没有任何价值。

于 2012-07-17T11:01:41.933 回答