GCC功能名称冲突

时间:2012-04-10 11:17:21

标签: c gcc

我正在测试一个示例代码的问题,因为我的abs函数没有返回正确的结果。 abs(-2)输出-2(顺便说一句,这是绝对值函数,如果不清楚的话)

在有点绝望之后,我最终得到了以下代码

#include <stdio.h>

unsigned int abs(int x) {
    return 1;
}

int main() {
    printf("%d\n", abs(-2));
    return 0;
}

这没有用,但它可以显示我的问题。当输出为1时,输出为-2。

如果我将函数名称更改为其他名称(例如abs2),则结果现在是正确的。此外,如果我将其更改为接收两个参数而不是一个,它也可以解决问题。

我明显的猜测:与标准abs功能发生冲突。但这仍然无法解释为什么输出为-2(如果使用标准abs函数则应为2)。我尝试检查两个版本的程序集输出(使用名为abs和abs2的函数)

这是两个程序集的diff输出:

23,25c23,25
< .globl abs
<   .type   abs, @function
< abs:
---
> .globl abs2
>   .type   abs2, @function
> abs2:
54c54
<   .size   abs, .-abs
---
>   .size   abs2, .-abs2
71c71,74
<   movl    -4(%rbp), %edx
---
>   movl    -4(%rbp), %eax
>   movl    %eax, %edi
>   call    abs2
>   movl    %eax, %edx

据我所知,第一个版本(函数名为abs)只是丢弃函数调用,因此使用参数x而不是abs(x)

总而言之:为什么会发生这种情况,特别是因为我无法找到解决此问题的方法。

在Debian Squeeze,ggc 4.4.5以及gcc 4.1.2

上测试

3 个答案:

答案 0 :(得分:7)

由于以下各方面的相互作用,海湾合作委员会正在耍弄你:

  • abs是内置函数;
  • 当标准(和内置)abs返回unsigned int时,您宣布abs返回signed int

尝试使用gcc -fno-builtin进行编译;在我的方框中,它给出了1的预期结果。如果没有该选项进行编译,但abs被声明为返回signed int,则会导致程序打印2

(此问题的真正解决方案是不要将库标识符用于您自己的功能。另请注意,您不应使用unsigned int打印%d。)

答案 1 :(得分:2)

gcc优化对abs()的调用,以使用其内置abs()。因此,如果您使用-fno-builtin选项(或将abs()定义为返回int),您会注意到您获得了正确的结果。根据{{​​3}}(引用):

  

GCC包含了许多功能的内置版本   标准C库。前缀为_ builtin 的版本将始终使用   被视为具有与C库函数相同的含义   如果指定-fno-builtin选项。 (参见C方言选项)很多   这些功能仅在某些情况下得到优化; 如果是的话   在特定情况下没有优化,调用库函数   将被发出

如果你包含stdlib.h,它首先声明abs(),你会在编译时遇到错误。

答案 2 :(得分:2)

听起来很像this bug,它来自2007年,并被注意到已修复。

当然,您应该尝试在没有GCC内在函数的情况下进行编译,即在编译时通过-fno-builtin(或只是-fno-builtin-abs来仅阻止abs())。