Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange Numerical Behaviour of gcc Linker

Tags:

c

gcc

linker

I have a problem with as simple a C code as the following:

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

int main () {
    printf ("%f\n", exp(1));
}

Replacing 1 with numbers smaller than 710 results in a successful compilation with the expected effect, but for numbers higher than that , I get a linker error, of all things:

/tmp/ccqVnsno.o: In function `main': 
test.c:(.text+0x1c): undefined reference to `exp'
collect2: error: ld returned 1 exit status

I have tested this for numbers under 1000 with the following bash script:

for i in {0..1000}; do
    sed -i -r "s:[0-9]+:${i}:" test.c
    gcc -o test test.c
    ./test
done

Putting the printf statements in a for loop with exp of the index variable results in the same linkage error, regardless of upper bound.

What's going on here? Is the compiler recognizing 710 as some sort of limit for long double? Then why is the linker catching the error? Sorry for credulity, I'm new to C.

like image 390
psacawa Avatar asked Sep 12 '17 08:09

psacawa


Video Answer


1 Answers

My guess is that for smaller numbers the GCC compiler optimizes the exp call into something else, but for larger numbers it needs the standard implementation which is in the math library. And the math library needs to be explicitly linked with.

You link with the math library by adding the option -lm when linking. It's the option -l (lower-case L) which tells the linker to link with a library, and m for the math library.


Regarding the possible optimizations of the exp function you can call it with a small number, and then use a disassembler to check the generated code.

like image 99
Some programmer dude Avatar answered Oct 26 '22 22:10

Some programmer dude