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
吗?
答案 0 :(得分:36)
为什么这是一个缩小的转换?
因为定义包括(强调我的意思):
C ++ 11 8.5.4 / 7 缩小转化是一种隐式转换 [...]从整数类型[...]到浮点类型,,除非源是常量表达式,转换后的实际值将适合目标类型,并且转换回原始类型时生成原始值。
u
不是常量表达式,因此无论源类型的所有可能值是否都可以在目标类型中表示,它都是一个缩小的转换。
unsigned
不是每个double
都能完美呈现吗?
这是实施的定义。在具有52位尾数的32位unsigned
和double
的常见情况下,情况就是如此;但是某些实现具有更大的unsigned
和/或更小的double
表示,因此依赖于该假设的代码不可移植。
答案 1 :(得分: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$
正如您所看到的,上面的代码没有任何警告或错误
答案 2 :(得分:1)
(让我们试试:) double
正好有52位有效(二进制)数字(根据ieee标准),而unsigned int
在某些其他系统上可能有好64位。因此,系统上实际的unsigned int
宽度对于此检查可能没有任何价值。