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

4

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

例如,给定以下代码:

int a, b;

我想把一个被检查过的 a += b 写成

__builtin_add_overflow(a, b, &a)

这个安全吗?


@EugeneSh。考虑到该函数族中至少有一些函数似乎在进行类型魔法,我认为它们是宏。 - EOF
@EugeneSh。即使C标准在某些情况下允许将函数实现为宏,那么您链接的页面上的__builtin_*_overflow_p()如何实现为真正的函数呢? - EOF
@EOF 我认为C标准不允许将函数实现为宏,以防止对主题的回答变得消极。我可能是错的,因为我没有在标准中看到过这种情况。但如果我写了这个,那就是这种情况 :) - Eugene Sh.
@EugeneSh.:在C11草案标准n1570的“7.1.4使用库函数”中有一个相当大的讨论,其中包括这个宝石:这样的宏可能不包含相应函数调用所包含的序列点。 - EOF
@EOF 很好的发现,但有点令人沮丧。但是这个脚注前面有一个“任何作为宏实现的库函数的调用都应该扩展为评估其每个参数一次的代码”。虽然没有指定评估的时间。所以理论上它可以先评估&a,破坏它,然后再评估a...如果我没有漏掉什么的话。 - Eugene Sh.
显示剩余8条评论
1个回答

3
我认为可以合理地假设,__builtin_add_overflow(a, b, &a) 的作用等同于 a += b
注意,也可以使用常量进行调用:
__builtin_add_overflow(10, 5, &a)

通常情况下,GCC会将其视为内置函数,这意味着它的调用在编译器内部被生成代码替换。它不像普通函数(在C语言中),因为没有带有声明的头文件。因此,它既不是内联函数也不是类似函数的宏。 6.54 内置函数执行带溢出检查的算术运算 编译器会尽可能使用硬件指令来实现这些内置函数,例如加法溢出后的条件跳转、进位等。
以下是一个示例(更好的示例在下面的评论中提供):
#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

3
实际上,对这个内置函数的返回值进行操作才能展示它的用途,例如像这样:https://godbolt.org/g/VYqS9K。 - Daniel Kamil Kozar
4
我知道这就是字面意思,但我觉得说它是“使用汇编语言实现”有点奇怪,因为对于内置函数来说并不需要一个“真正”的实现。这有点像说a/b是用汇编实现的。对于真正使用汇编实现的函数,存在代码生成方面的影响,而这并不适用于内置函数。 - zneak
我一直基于这是一个合理的假设来进行,而且在我尝试过的平台上似乎都成立。只是我找不到实际的声明或示例来确认它是否可移植。我认为问题的评论有所帮助 - 这是一个函数(或应该表现得像),并且输入是按值传递的。 - Toby Speight
@TobySpeight:我会小心地称其为语言意义上的函数。如果是这样,那么它在哪里声明?C语言要求在函数调用之前必须有声明,否则会引发编译时错误。 - Grzegorz Szpetkowski

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接