乍一看,这个问题看起来像是如何检测整数溢出的重复?然而,它实际上是显着不同的.
我发现虽然检测无符号整数溢出非常简单,但在C/C++中检测带符号的溢出实际上比大多数人想象的要困难.
最明显但又天真的方式是这样的:
int add(int lhs, int rhs)
{
int sum = lhs + rhs;
if ((lhs >= 0 && sum < rhs) || (lhs < 0 && sum > rhs)) {
/* an overflow has occurred */
abort();
}
return sum;
}
Run Code Online (Sandbox Code Playgroud)
这个问题是根据C标准,有符号整数溢出是未定义的行为. 换句话说,根据标准,只要您甚至导致签名溢出,您的程序就像取消引用空指针一样无效.因此,您不能导致未定义的行为,然后尝试在事后检测溢出,如上面的后置条件检查示例.
尽管上面的检查很可能适用于许多编译器,但你不能指望它.实际上,因为C标准说未定义有符号整数溢出,所以一些编译器(如GCC)将在设置优化标志时优化上述检查,因为编译器假定有符号溢出是不可能的.这完全打破了检查溢出的尝试.
因此,检查溢出的另一种可能方法是:
int add(int lhs, int rhs)
{
if (lhs >= 0 && rhs >= 0) {
if (INT_MAX - lhs <= rhs) {
/* overflow …Run Code Online (Sandbox Code Playgroud) 我一直在阅读Linux内核(特别是2.6.11).我发现了以下定义:
#define unlikely(x) __builtin_expect(!!(x), 0)
Run Code Online (Sandbox Code Playgroud)
(来自linux-2.6.11/include/linux/compiler.h:61 lxr链接)
什么!! 完成?为什么不使用(x)?
也可以看看:
From what I've read, seems like there are 9 different flags. Is it possible to read/change them directly? I know I can know for example if the zero flag is set after doing a cmp/jmp instruction, but I'm asking if it's possible to do something like
mov eax, flags
Run Code Online (Sandbox Code Playgroud)
or something.
Also, for writing, is it possible to set them by hand?
在执行数学运算之后,比如乘以两个整数,是否可以使用C++访问CPU中的溢出标志寄存器?如果没有其他快速方法来检查溢出?
如何检测D中的整数溢出?(检查携带标志?)
原始示例:
ubyte a = 100;
ubyte b = 200;
ubyte c = a + b;
// c can't represent 300; how to detect the overflow now?
Run Code Online (Sandbox Code Playgroud)
修改后的例子:
uint a = 2_000_000_000;
uint b = 3_000_000_000;
uint c = a + b;
// c can't represent 5_000_000_000; how to detect the overflow now?
Run Code Online (Sandbox Code Playgroud)
还有乘法和前/后增量.