我想x
通过套接字传递一个32位有符号整数.为了让接收器知道预期的字节顺序,我htonl(x)
在发送之前调用.htonl
期待一个,uint32_t
但我想确定当我把我int32_t
带到一个时会发生什么uint32_t
.
int32_t x = something;
uint32_t u = (uint32_t) x;
Run Code Online (Sandbox Code Playgroud)
总是这样的情况,每个字节x
和u
每个字节都完全相同吗?怎么回事:
uint32_t u = something;
int32_t x = (int32_t) u;
Run Code Online (Sandbox Code Playgroud)
我意识到负值会转换为大的无符号值,但这并不重要,因为我只是回到了另一端.但是,如果使用实际字节进行混乱,那么我无法确定返回将返回相同的值.
有(1):
// assume x,y are non-negative
if(x > max - y) error;
Run Code Online (Sandbox Code Playgroud)
并且(2):
// assume x,y are non-negative
int sum = x + y;
if(sum < x || sum < y) error;
Run Code Online (Sandbox Code Playgroud)
哪个是首选或有更好的方法.
我只是想知道灾难性的整数溢出是多么的真实.采用以下示例程序:
#include <iostream>
int main()
{
int a = 46341;
int b = a * a;
std::cout << "hello world\n";
}
Run Code Online (Sandbox Code Playgroud)
由于a * a
32位平台上的溢出和整数溢出触发了未定义的行为,我是否有任何hello world
实际出现在屏幕上的保证?
我根据以下标准引文从我的问题中删除了"已签名"部分:
(§5/ 5 C++ 03,§5/ 4 C++ 11)如果在评估表达式期间,结果未在数学上定义或未在其类型的可表示值范围内,则行为未定义.
(§3.9.1/ 4)声明的无符号整数
unsigned
应遵守算术模2 ^ n的定律,其中n是该特定整数大小的值表示中的位数.这意味着无符号算术不会溢出,因为无法由结果无符号整数类型表示的结果以比模式生成的无符号整数类型所表示的最大值大1的数量为模.
由于可能,在实际加/减之前有很多关于检测整数溢出的问题undefined behavior
.所以,我的问题是
为什么它会首先产生这个undefined behavior
?
我可以想到两个原因:
1)在这种情况下生成异常的处理器.当然,它可以切换,很可能是一个写得很好的CRT会做到这一点.
2)使用数字的其他二进制表示的处理器(1的补码?基数10?).在这种情况下,未定义的行为将表现为不同的结果(但不会崩溃!).好吧,我们可以忍受这一点.
那么,为什么有人会避免造成它呢?我错过了什么吗?