C++ 将负常量双精度强制转换为无符号将导致0,而非常量双精度则可以
我有以下代码:C++ 将负常量双精度强制转换为无符号将导致0,而非常量双精度则可以,c++,constants,static-cast,C++,Constants,Static Cast,我有以下代码: #include <iostream> int main() { double val = -400.0; const double constVal = -400.0; std::cout << val << std::endl; std::cout << static_cast<unsigned>(val) << std::endl; std::cout <
#include <iostream>
int main() {
double val = -400.0;
const double constVal = -400.0;
std::cout << val << std::endl;
std::cout << static_cast<unsigned>(val) << std::endl;
std::cout << constVal << std::endl;
std::cout << static_cast<unsigned>(constVal) << std::endl;
return 0;
}
为什么会发生这种情况?适度的谷歌搜索在这件事上没有任何表现。来源:
浮点类型的prvalue可以转换为任意类型的prvalue
整数类型。小数部分被截断,即
小数部分被丢弃。如果该值不能放入
目标类型,行为未定义(即使目标
类型为无符号,模运算不适用)。如果
目标类型为bool,这是一种布尔转换(见下文)
-400不能放入未签名的中,因此行为未定义。试图对任何类型的一致性进行推理都是徒劳的
由于这是未定义的行为,编译器在这种情况下可以做任何它想做的事情。通常情况下,他们会做任何让他们(定义的)行为的其余部分更容易编码的事情。尽管如此,编译器不太可能让恶魔从你的鼻子里飞出来,但你不应该期望有任何特别的行为。有什么吗?它能射死你吗,耶稣;)@是的,如果我是一个赌徒,我不会赌它会杀了你。但是,如果它向你开枪,它至少会符合标准。只要不要在gcc中打开-woOptimize out non-pedantic programmers
标志,你就会没事的。啊哈!在思考了大约10分钟后,我意识到区别不在于第二个值是const
,而是它也是(偶然的)constepr
。因此,第二次强制转换是在编译时计算的,第一次是在运行时计算的。@MooingDuck这实际上是一个很好的答案,“UB,鼻腔恶魔”的一个很好的刷新。更好的标题可能是“将负值强制转换为未签名的
会导致奇怪的行为”@SergeyA:这不是一个答案,因为正确的答案是“UB,鼻腔恶魔”。解释的行为只是一个有趣的旁注。“不是答案”也将是高度特定于编译器和优化级别的,我想。这是一个很好的理论解释为什么会发生这种情况(对于这种特定的编译器和优化级别组合)。
-400
4294966896
-400
0