简体   繁体   中英

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(-2) was outputing -2 (this, by the way, is suposed to be the absolute value function, if that was unclear)

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.

if i change the function name to something else (abs2 for example), the result is now correct. Also, if i change it to receive two arguments instead of one, it also fixes the problem.

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). I tried checking the assembly output of both versions (with the function named abs and abs2)

Here's the diff output for both assemblys:

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)

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

GCC is playing tricks on you due to the interplay of the following:

  • abs is a built-in function;
  • you're declaring abs to return unsigned int while the standard (and built-in) abs returns signed int .

Try compiling with gcc -fno-builtin ; on my box, that gives the expected result of 1 . Compiling without that option but with abs declared as returning signed int causes the program to print 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 .)

gcc optimizes the call to abs() to use its built-in abs() . So if you use the -fno-builtin option (or define your abs() as returning int ), you'll notice you get the correct result. According tothis (quoting):

GCC includes built-in versions of many of the functions in the standard C library. 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. (see C Dialect Options) Many of these functions are only optimized in certain cases; if they are not optimized in a particular case, a call to the library function will be emitted .

Had you included stdlib.h , which declares abs() in the first place, you'd get an error at compile time.

Sounds a lot like this bug , which is from 2007 and noted as being fixed.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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