I have a sample file here:
#include <stdio.h>
#include <math.h>
int main(){
printf("%f\n", log(10));
}
When I compile it with gcc sample.c -o a
it works just fine. I can run it with ./a
and it produces the output 2.302585
like expected.
Yet, when my file looks like this:
#include <stdio.h>
#include <math.h>
int main(){
double a = 10;
printf("%f\n", log(a));
}
it does not compile with gcc sample.c -o a
. Instead, I have to use gcc sample.c -o a -lm
so that I can apparently tell it to "link math"...That's where I don't really follow, why wouldn't I have to link math in the first example? And what exactly does it even mean to have to "link math"? It's been a while since I've worked with C compilers, so forgive me if this is poor question.
Check the disassembly, and you'll likely find that the compiler is optimizing the call to
log()
out entirely in the first case (so there's nothing to link), but not in the second. In this particular case, glibc defines:in
math.h
, for instance, and any standard library function can be implemented as a macro, so it can calculate some of these things without a function call.The math library functions may not be called, according to GCC document, some inline functions are defined and may be called instead in certain circumstances.
For some reasons gcc optimizes log(const) even with -O0. So there's no log() call in the first case. Check assembly to verify:
clang, for example doesn't optimize it out on O0. But at O2 gcc optimizes the call in both cases.