简体   繁体   English

GCC function 名称冲突

[英]GCC function name conflict

I was having some problems with a sample code i was testing, since my abs function was not returning the correct result.我在测试示例代码时遇到了一些问题,因为我的 abs function 没有返回正确的结果。 abs(-2) was outputing -2 (this, by the way, is suposed to be the absolute value function, if that was unclear) abs(-2) 输出 -2(顺便说一句,如果不清楚的话,这应该是绝对值 function)

After getting a bit desperate, i eventually had the following code在有点绝望之后,我最终得到了以下代码

#include <stdio.h>

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

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

This does nothing useful but it serves to show my problem.这没有任何用处,但可以说明我的问题。 This was outputing -2, when it was expected to output 1.这是输出 -2,而预期为 output 1。

if i change the function name to something else (abs2 for example), the result is now correct.如果我将 function 名称更改为其他名称(例如 abs2),结果现在是正确的。 Also, if i change it to receive two arguments instead of one, it also fixes the problem.此外,如果我将其更改为接收两个 arguments 而不是一个,它也可以解决问题。

My obvious guess: a conflict with the standart abs function. But this still doesn't explain why the output is -2 (it should be 2, if using the standart abs function).我明显的猜测:与标准 abs function 冲突。但这仍然不能解释为什么 output 是 -2(如果使用标准 abs 函数,它应该是 2)。 I tried checking the assembly output of both versions (with the function named abs and abs2)我尝试检查两个版本的程序集 output(function 名为 abs 和 abs2)

Here's the diff output for both assemblys:这是两个程序集的差异 output:

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

From what i understand, the first version (where the function is named abs) is simply discarding the function call, thus using the parameter x instead of abs(x)据我了解,第一个版本(其中 function 被命名为 abs)只是丢弃了 function 调用,因此使用参数 x 而不是 abs(x)

So to sum up: why does this happen, especially since i couldn't find a way to get any sort of warning or error about this.总结一下:为什么会发生这种情况,特别是因为我找不到一种方法来获得有关此的任何警告或错误。

Tested on Debian Squeeze, ggc 4.4.5, and also on gcc 4.1.2在 Debian Squeeze、ggc 4.4.5 和 gcc 4.1.2 上测试

GCC is playing tricks on you due to the interplay of the following:由于以下因素的相互作用,GCC 正在捉弄你:

  • abs is a built-in function; abs是内置的function;
  • you're declaring abs to return unsigned int while the standard (and built-in) abs returns signed int .您声明abs返回unsigned int而标准(和内置) abs返回signed int

Try compiling with gcc -fno-builtin ;尝试使用gcc -fno-builtin进行编译; on my box, that gives the expected result of 1 .在我的盒子上,给出了1的预期结果。 Compiling without that option but with abs declared as returning signed int causes the program to print 2 .不使用该选项但将abs声明为返回signed int进行编译会导致程序打印2

(The real solution to this problem is to not use library identifiers for your own functions. Also note that you shouldn't be printing an unsigned int with %d .) (此问题的真正解决方案是不要为您自己的函数使用库标识符。另请注意,您不应该使用%d打印unsigned int 。)

gcc optimizes the call to abs() to use its built-in abs() . gcc优化了对abs()的调用以使用其内置的abs() So if you use the -fno-builtin option (or define your abs() as returning int ), you'll notice you get the correct result.因此,如果您使用-fno-builtin选项(或将abs()定义为返回int ),您会注意到您得到了正确的结果。 According tothis (quoting):根据这个(引用):

GCC includes built-in versions of many of the functions in the standard C library. GCC 包含标准 C 库中许多函数的内置版本。 The versions prefixed with _ builtin will always be treated as having the same meaning as the C library function even if you specify the -fno-builtin option.以 _ builtin为前缀的版本将始终被视为与 C 库 function 具有相同的含义,即使您指定了 -fno-builtin 选项。 (see C Dialect Options) Many of these functions are only optimized in certain cases; (参见 C 方言选项)其中许多功能仅在某些情况下进行了优化; if they are not optimized in a particular case, a call to the library function will be emitted .如果它们在特定情况下没有优化,将发出对库 function 的调用

Had you included stdlib.h , which declares abs() in the first place, you'd get an error at compile time.如果你包含了stdlib.h ,它首先声明了abs() ,你会在编译时得到一个错误。

Sounds a lot like this bug , which is from 2007 and noted as being fixed.听起来很像这个错误,它来自 2007 年并已修复。

You should of course try to compile without GCC's intrinics, ie pass -fno-builtin (or just -fno-builtin-abs to snipe out only abs() ) when compiling.您当然应该尝试在没有 GCC 内在函数的情况下进行编译,即在编译时传递-fno-builtin (或仅传递 -fno- -fno-builtin-abs以仅删除abs() )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM