Search code examples
clinker-errorsflagsundefined-referencemath.h

Error linking code with `floor();`, `ceil();` and `pow();`


I am coding under GNU/Linux Debian 8.5

I have a simple program.

If I compile this with gcc prog.c it is OK!

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

int main(int argc, char const *argv[]) {

    float _f = 3.1415f;

    floor(_f);
    ceil(_f);

    return 0;
}

Bud if I add pow(), it says that it cannot find pow and I need to add gcc prog.c -lm to make it right.

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

int main(int argc, char const *argv[]) {

    float _f = 3.1415f;

    floor(_f);
    ceil(_f);
    pow(_f, 2);

    return 0;
}

If I am right, the pow(), ceil(), floor() are all from <math.h>?

So why don't floor() and ceil() throw a compilation error, and pow() does, without -lm flag?


Solution

  • Technically all of them require -lm to work. All of their man pages include this line:

    Link with -lm.

    But yours is not a compiler error but a linker error, that is your program compiles fine, but then when linking if you don't use -lm it is unable to find the implementation of pow() but it actually finds the implementation of ceil().

    That is probably because in your architecture/configuration ceil() is an inline or intrinsic function, maybe there is a simple CPU instruction to do it, so no library is necessariy. But pow() is not so you need to link libm.

    UPDATE: I've just made some experiments, and with -O0 all your functions require the -lm but with -O2 only pow(). Tinkering about that I found the file /usr/include/bits/mathinline.h with the inline implementations of ceil() and floor()...