Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I use __builtin_*_overflow as += or *=?

Tags:

c

gcc

Is it legal to use a single variable for both source and destination of GCC's __builtin_*_overflow functions?

For example, given

int a, b;

I would like to write a checked a += b as

__builtin_add_overflow(a, b, &a)

Is this safe?

like image 602
Toby Speight Avatar asked Sep 18 '25 15:09

Toby Speight


1 Answers

I think it's sane to assume, that __builtin_add_overflow(a, b, &a) will work as a += b.

Note, that it may be as well invoked with constants:

__builtin_add_overflow(10, 5, &a)

Normally, GCC will treat it as intrinsic function, which means that its call is replaced internally by compiler with generated code. It's not treated as normal function (in the C sense), since there is no header file with its declaration. Hence, it's neither a inline function nor function-like macro.

6.54 Built-in Functions to Perform Arithmetic with Overflow Checking

The compiler will attempt to use hardware instructions to implement these built-in functions where possible, like conditional jump on overflow after addition, conditional jump on carry etc.

Here is an example (the better one is provided in comment below):

#include <stdio.h>

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

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

which translates on GCC 6.3.0 with -O0 into (see 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
like image 154
Grzegorz Szpetkowski Avatar answered Sep 21 '25 09:09

Grzegorz Szpetkowski