【发布时间】:2019-03-06 05:55:19
【问题描述】:
我在我的 gcc 版本 4.6 中构建了一个简单的小程序代码,它有一个不受支持的函数 __builtin_add_overflow。考虑到一些原因,我不想更新我的 gcc 版本。那么我的 gcc 版本中的什么函数可以用来替换那个函数呢?
【问题讨论】:
我在我的 gcc 版本 4.6 中构建了一个简单的小程序代码,它有一个不受支持的函数 __builtin_add_overflow。考虑到一些原因,我不想更新我的 gcc 版本。那么我的 gcc 版本中的什么函数可以用来替换那个函数呢?
【问题讨论】:
溢出检测取决于变量的类型。
如果它们是无符号的,则足以检测结果是否低于其操作数之一。
inline unsigned_overflow(unsigned a, unsigned b){
return (a+b)<a;
如果两者都是无符号的,则只有当操作数的符号相同且结果的符号不同时,才会发生溢出。因此,如果 result 的符号与其两个操作数的符号不同,则会出现溢出。
inline signed_overflow(int a, int b){
unsigned ua=a, ub=b;
return (int)(((ua^(ua+ub))&((ub^(ua+ub)))<0 ;
【讨论】:
signed_overflow 仅适用于-fwrapv。您需要以无符号类型执行可能溢出的加法。
^/& hack,你真的需要那个 GCC 扩展。
您需要自己编写。如果参数是无符号的,那么做起来并不难(只需比较总和是否小于较大输入类型中的加数之一)。有符号整数算术的溢出检查可能相当复杂,尤其是在所有三种整数类型都不同的情况下。有一个 GCC 扩展会有所帮助:从无符号类型到有符号类型的转换不会触发未定义的行为,但会根据二进制补码算法减少值。所以你可以使用这个:
unsigned x1 = x1;
unsigned y1 = y1;
bool overflow = (int) (((x + y) ^ x) & (x + y) ^ y))) < 0;
Hacker's Delight 这本书广泛讨论了这些主题。
【讨论】: