C:表达式计算中的隐式转换和整数溢出
时间:2020-03-05 18:49:36 来源:igfitidea点击:
让我们看一下代码
int a, b, c; ... if ((a + b) > C)
如果我们将a和b的值相加,并且总和超过int的最大值,比较的完整性是否会受到损害?我当时在想可能会有一个隐式的强制转换或者溢出位检查,这将在对该表达式的求值中考虑。
解决方案
回答
C不会做这种事情。它会静默溢出,并可能导致不正确的比较。我们可以自己上演,但不会自动完成。
回答
我相信这可能是特定于平台的。查看有关如何处理溢出的C文档...
啊,是的,并且不会自动发生up ...
回答
请参阅《 K&R》一书中的2.7节,类型转换
回答
测试确认GCC 4.2.3将简单地与溢出结果进行比较:
#include <stdio.h> int main() { int a, b, c; a = 2000000000; b = 2000000000; c = 2100000000; printf("%d + %d = %d\n", a, b, a+b); if ((a + b) > c) { printf("%d + %d > %d\n", a, b, c); } else { printf("%d + %d < %d\n", a, b, c); } return 0; }
显示以下内容:
2000000000 + 2000000000 = -294967296 2000000000 + 2000000000 < 2100000000
回答
如果向上转换没有获得任何收益(无法保证C中的sizeof(long)> sizeof(int)),则可以使用以下条件进行比较,并确定如果可以使用,则向上溢出的检查几乎肯定会更快, 尽管。
#if !defined(__GNUC__) || __GNUC__<2 || (__GNUC__==2 && __GNUC_MINOR__<96) # define unlikely(x) (x) #else # define unlikely(x) (__extension__ (__builtin_expect(!!(x), 0))) #endif /* ---------- * Signed comparison (signed char, short, int, long, long long) * Checks for overflow off the top end of the range, in which case a+b must * be >c. If it overflows off the bottom, a+b < everything in the range. */ if(a+b>c || unlikely(a>=0 && b>=0 && unlikely(a+b<0))) ... /* ---------- * Unsigned comparison (unsigned char, unsigned short, unsigned, etc.) * Checks to see if the sum wrapped around, since the sum of any two natural * numbers must be >= both numbers. */ if(a+b>c || unlikely(a+b<a)) ... /* ---------- * To generate code for the above only when necessary: */ if(sizeof(long)>sizeof(int) ? ((long)a+b>c) : (a+b>c || unlikely(a>=0 && b>=0 && unlikely(a+b<0))) ...
宏或者内联函数的理想选择。我们可以根据需要拉"不太可能",但是它们可以帮助缩小并加快GCC生成的代码。