我可以使用__builtin _ * _ overflow作为+ =或* =吗?

时间:2017-01-17 18:37:47

标签: c gcc

对GCC __builtin_*_overflow函数的源和目标使用单个变量是否合法?

例如,给定

int a, b;

我想将支票a += b写为

__builtin_add_overflow(a, b, &a)

这样安全吗?

1 个答案:

答案 0 :(得分:1)

我认为可以理解,__builtin_add_overflow(a, b, &a)将作为a += b工作。

注意,它也可以用常量调用:

__builtin_add_overflow(10, 5, &a)

通常,GCC会将其视为内部函数,这意味着它的调用在内部被编译器替换为生成的代码。它不被视为正常函数(在C意义上),因为没有带有声明的头文件。因此,它既不是内联函数也不是函数式宏。

6.54 Built-in Functions to Perform Arithmetic with Overflow Checking

  

编译器将尝试使用硬件指令来实现   尽可能使用这些内置函数,如条件跳转   添加后溢出,有条件跳转等。

以下是一个示例(下面的comment中提供了更好的示例):

#include <stdio.h>

int main(void)
{
    int a = 10;
    int b = 5;

    __builtin_add_overflow(a, b, &a);
    printf("%d\n", a);
}

将GCC 6.3.0与-O0转换​​为(参见godbolt.org/g/UJqenc):

    mov     DWORD PTR [rbp-8], 10      ; place a and b on stack
    mov     DWORD PTR [rbp-4], 5
    mov     edx, DWORD PTR [rbp-8]     ; copy a and b into GP registers
    mov     eax, DWORD PTR [rbp-4]
    add     eax, edx                   
    mov     DWORD PTR [rbp-8], eax     ; move the sum into a
    mov     eax, DWORD PTR [rbp-8]
    mov     esi, eax                   ; pass a into printf
    mov     edi, OFFSET FLAT:.LC0
    mov     eax, 0
    call    printf