gpt4 book ai didi

c++ - 基于整数溢出的 GCC 优化

转载 作者:搜寻专家 更新时间:2023-10-31 00:35:26 29 4
gpt4 key购买 nike

最近我讨论过有人想像这样检查有符号整数溢出 if (A + B < 2 * max(A, B)) .让我们暂时忽略逻辑本身的错误,并讨论 C/C++ 上下文中的有符号整数溢出。 (我相信它完全继承了 C 标准的这一部分)。

哪些需要有符号整数溢出的检查会被当前的 GCC 优化掉,哪些不会?

由于原始文本的表述不尽如人意,而且显然存在争议,我决定稍微更改一下问题,但将原始文本保留在下面。

下面使用的所有示例都经过测试 gcc 版本 4.7.2 (Debian 4.7.2-5)并使用 -O3 编译

也就是说,它是未定义的,GCC 臭名昭著地使用它来执行一些分支简化。我想到的第一个例子是

int i = 1;
while (i > 0){
i *= 2;
}

这会产生一个无限循环。这种优化开始的另一种情况是

if (A + 2 < A){
/* Handle potential overflow */
}

其中,假设 A是有符号整数类型,溢出分支被完全删除。

更有趣的是,一些容易证明整数溢出的情况没有被触及,例如

if (INT_MAX + 1 < 0){
/* You wouldn't write this explicitly, but after static analysis the program
could be shown to contain something like this. */
}

这会触发您期望使用二进制补码表示的分支。同样,此代码保留条件分支不变

int C = abs(A);
if (A + C < 0){
/* For this to be hit, overflow or underflow had to happen. */
}

现在的问题是,是否有一个看起来大致像 if (A + B < C) 的模式?或 if (A + B < c) ,那会被优化掉吗?当我在写这篇文章之前四处搜索时,似乎应该优化最后一个片段,但我无法在不明确使用常量操作的溢出检查中重现这种错误。

最佳答案

许多编译器会将涉及有符号整数或指针的表达式替换为“false”,例如

a + 1 < a // signed integer a
p + 1 < p // Pointer p

当表达式仅在未定义行为的情况下为真时。另一方面,这允许

for (char* q = p; q < p + 2; ++q) ...

被内联,替换 q = p 和 q = p + 1,没有任何检查,所以这是一件好事。

if (A + abs (A) < 0)

对于许多编译器来说可能太复杂了。请注意,对于无符号整数,没有未定义的行为。因此,使用无符号 32 位整数和 64 位指针的循环往往比必要的要慢,因为必须考虑环绕行为。对于无符号的 32 位整数和 64 位指针,有可能

&p [i] > &p [i+1]

没有未定义的行为(不是 64 位整数或 32 位指针)。

关于c++ - 基于整数溢出的 GCC 优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23889022/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com