-2

Let us suppose the following piece of code:

#include <stdio.h>
#include <math.h>

int abs(int x){
    return x*2;
}

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

When I compile and execute it, I noticed that the abs function of math.h is being used. Actually, this happens even if I remove the #include <math.h>. But I don't understand what is happening here.

Zaratruta
  • 2,097
  • 2
  • 20
  • 26
  • 1
    what compiler are you using? – Daniel A. White Feb 07 '23 at 20:16
  • 1
    `abs` is probably a defined macro. – konsolebox Feb 07 '23 at 20:18
  • Using `#include `, you _will_ get a conflict at _compile_ time (an error). But, if you remove it, there shouldn't be an issue. And, unless you're doing `-lm`, most compilers/linkers will _not_ include (e.g.) `libm.so` by default. There may be exceptions for some compilers. And, even so, the linker should favor _your_ `abs` code because it's in the same `.c` file. So, as Daniel asked, what compiler, linker, libc/libm are you using on what system (e.g. linux, *BSD, etc.)? – Craig Estey Feb 07 '23 at 20:21
  • When I try this with MSVC it is plain that the function is used. – Weather Vane Feb 07 '23 at 20:22
  • Related: [Macro and function with same name](https://stackoverflow.com/questions/1951885/macro-and-function-with-same-name). – Weather Vane Feb 07 '23 at 20:28
  • @Craig Estey, Re "*Using `#include `, you will get a conflict at compile time (an error)*", [Not with gcc](https://godbolt.org/z/Ybd1K33xn) – ikegami Feb 07 '23 at 20:45
  • 1
    The standard library function `int abs(int x);` is declared in `` (not ``). But given the constant argument, the compiler is probably evaluating the result of `abs(-2)` at compile time. Try using a loop with a variable argument to `abs()` and see what happens. – Jonathan Leffler Feb 07 '23 at 20:45
  • @Daniel A. White gcc on Linux exhibits the behaviour described. – ikegami Feb 07 '23 at 20:46
  • @Jonathan Leffler Re "*Try using a loop with a variable argument to abs() and see what happens.*", [No change](https://godbolt.org/z/MMf179boT) – ikegami Feb 07 '23 at 20:48
  • @ikegami: yes — judging from the generated assembler (and the program behaviour), it does seem that GCC knows how to use `abs()` without calling the library function (or any other function than `printf()`) — it uses a single instruction to do the job on an x86/64 machine. Moral: don't try overriding the standard C library functions — it may not work. – Jonathan Leffler Feb 07 '23 at 20:58
  • Actually, it can be two instructions — a `neg` and a `cmov` instruction; but still quicker than an actual function call and return by a large margin. – Jonathan Leffler Feb 07 '23 at 21:09

1 Answers1

5
  1. abs is not declared in math.h only stdlib.h.
  2. GCC uses built-in abs and ignores your code.
  3. You need to use -fno-builtin flag and the program will behave your way.

enter image description here

https://godbolt.org/z/v9xM3jbbj

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
0___________
  • 60,014
  • 4
  • 34
  • 74