for*_*818 5 c++ unsigned type-conversion
当我运行这个时:
int main() {
unsigned a = 5;
std::cout << -a << std::endl;
int b = -a;
std::cout << b << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我明白了:
4294967291
-5
Run Code Online (Sandbox Code Playgroud)
看起来它有效,我可以取 an 的负数unsigned并将其分配给 an int,但这真的总是可以吗?为什么?
当我尝试一些对我来说看起来类似的情况时:
int c = 1;
int d = 3;
double x = c/d;
std::cout << x << std::endl;
Run Code Online (Sandbox Code Playgroud)
我明白了0(正如预期的那样)。
PS:也许有一个骗局,但我没有找到它,我能找到的最接近的是这个
不。你有未定义的行为可能性。
\n\n下面是一个反例,当将否定分配unsigned int给 an时,会产生 UB int:
unsigned u = (unsigned)std::numeric_limits<int>::max() - 1;\nstd::cout << "max int" << std::numeric_limits<int>::max() << \'\\n\';\nstd::cout << "as unsigned - 1" << u << \'\\n\';\nstd::cout << "negated:" << -u << \'\\n\';\nstd::cout << std::boolalpha << ( std::numeric_limits<int>::max() < -u ) << \'\\n\';\nint s = -u;\nstd::cout << s << \'\\n\';\nRun Code Online (Sandbox Code Playgroud)\n\n在我的机器上:\n int\ 的最大值是 2\'147\'483\'647,但求反的unsigned int值为 2\'147\'483\'650;该值大于 可以表示的最大值int。知道有符号溢出是未定义的行为。因此,该算法对于所有可能的值来说并不安全。
标准(2016-07-12:N4604)字样:
\n\n\n\n\n如果在计算表达式期间,结果未在数学上定义或不在其类型的可表示值范围内,则行为未定义。[ 注意:除以 0 的处理、使用零除数形成余数以及所有 \xef\xac\x82oating point\n 例外情况因机器而异,有时可以通过库函数进行调整。\xe2\x80\x94 尾注]
\n
将来,您可以使用{}-style 初始化来防止此类问题:
unsigned a = 5;\nstd::cout << -a << \'\\n\';\nint b{ -a }; // compiler detects narrowing conversions, warning/error\nstd::cout << b << \'\\n\';\nreturn 0;\nRun Code Online (Sandbox Code Playgroud)\n\n请注意,即使您知道这-a将是一个可以由 表示的值int,您的编译器仍然会警告您。
关于签名溢出:
\n\n\n\n关于 C 和 C++ 中定义明确的无符号溢出:
\n\n为什么无符号整数溢出定义了行为,但有符号整数溢出却没有定义?
\n\n关于隐式转换:
\n\nhttp://en.cppreference.com/w/cpp/language/implicit_conversion
\n| 归档时间: |
|
| 查看次数: |
291 次 |
| 最近记录: |