88

I have this simple code:

max = (int) sqrt (number);

and in the header I have:

#include <math.h>

But application still says undefined reference to sqrt. Do you see any problem here? It looks like everything should be okay.

Marco Bonelli
  • 63,369
  • 21
  • 118
  • 128
Waypoint
  • 17,283
  • 39
  • 116
  • 170
  • 1
    Which complains, the linker or the compiler? If you can post the exact error that'd probably clear things up. – Tommy Mar 09 '11 at 16:36
  • 1
    compiler write this complain, problem is, that app don't even built... – Waypoint Mar 09 '11 at 16:40
  • 8
    The problem is not in your program but in your system's implementation of the C library. It's still following 1970s/1980s legacy conventions where the math functions are in a separate library and not linked by default. – R.. GitHub STOP HELPING ICE Mar 09 '11 at 18:52
  • Related: https://stackoverflow.com/questions/1033898/why-do-you-have-to-link-the-math-library-in-c?noredirect=1&lq=1 – Nate Eldredge Feb 10 '21 at 23:35

5 Answers5

123

You may find that you have to link with the math libraries on whatever system you're using, something like:

gcc -o myprog myprog.c -L/path/to/libs -lm
                                       ^^^ - this bit here.

Including headers lets a compiler know about function declarations but it does not necessarily automatically link to the code required to perform that function.

Failing that, you'll need to show us your code, your compile command and the platform you're running on (operating system, compiler, etc).

The following code compiles and links fine:

#include <math.h>
int main (void) {
    int max = sqrt (9);
    return 0;
}

Just be aware that some compilation systems depend on the order in which libraries are given on the command line. By that, I mean they may process the libraries in sequence and only use them to satisfy unresolved symbols at that point in the sequence.

So, for example, given the commands:

gcc -o plugh plugh.o -lxyzzy
gcc -o plugh -lxyzzy plugh.o

and plugh.o requires something from the xyzzy library, the second may not work as you expect. At the point where you list the library, there are no unresolved symbols to satisfy.

And when the unresolved symbols from plugh.o do appear, it's too late.

Marco Bonelli
  • 63,369
  • 21
  • 118
  • 128
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • @paxdiablo : and in the case of [µClibc](https://bugs.gentoo.org/show_bug.cgi?id=549860) for csqrt? – user2284570 May 18 '15 at 23:37
  • @user2284570, that sounds like it would be better posted as a question ("How do I link in the math libraries for uClibc?" or something like that). A question gets seen by _many_ more people than a comment. – paxdiablo May 19 '15 at 00:04
  • 3
    Also pay attention to the order of the linked libraries. I have found that I've had -lm too early in the command line and that moving it to the end solves related error messages. This also seems to be gcc version dependent (some older versions didn't mind as much). – Kevin Bullaughey Jul 10 '15 at 02:50
  • Good pointer @KevinBullaughey I also had to move another link option to the back (-lpthread). – Tony Martin Mar 07 '16 at 11:43
  • Also note that `-lm` _must_ come _last_! See here: [Undefined reference to `sin`](https://stackoverflow.com/a/12165016/4561887). – Gabriel Staples Mar 14 '22 at 04:00
  • 1
    @Gabriel, I thought my final section ("Just be aware ...") covered that. In any case it is not the case that it must come last, it just can't come before anything that exclusively needs things from it. By that, I mean `user_of_sin -lm user_of_cos user_of_xx -lprovider_of_xx` is fine for everything except `cos` (assuming `sin` and `cos` are *separate* objects within the library). Granted, last is probably the safest place to put it (assuming it needs nothing) but I'm feeling pedantic today :-) – paxdiablo Mar 14 '22 at 04:06
  • 1
    @paxdiablo, thanks for the clarification. Yes, your additional comment is _pedantically correct_ (meaning technically correct), while my comment is _practically correct_ (meaning: correct as a general rule of thumb in a practical sense). I can't think of any cases where just putting all libraries last would _not_ be functional and what you want, although, _technically_, as you said, the library only needs to come right after the object file or source file which needs it. – Gabriel Staples Mar 14 '22 at 04:27
  • 1
    @Gabriel, no probs. I agree that all libs should come after all objects. I *have* been burnt before by circular library dependencies, requiring a monstrosity like `-laaa -lbbb -laaa` to ensure the dependencies are resolved. I've even seen cases where this round trip was required multiple times when different objects within the libraries had complex circular dependencies. I don't know why GNU `ld` didn't just at least provide an *option* for going back to previously given libs to satisfy new unresolved symbols. – paxdiablo Mar 14 '22 at 04:35
31

I suppose you have imported math.h with #include <math.h>

So the only other reason I can see is a missing linking information. You must link your code with the -lm option.

If you're simply trying to compile one file with gcc, just add -lm to your command line, otherwise, give some informations about your building process.

krtek
  • 26,334
  • 5
  • 56
  • 84
3

Just adding the #include <math.h> in c source file and -lm in Makefile at the end will work for me.

    gcc -pthread -o p3 p3.c -lm
Hassan Rahman
  • 4,953
  • 1
  • 34
  • 32
3

Here are my observation, firstly you need to include the header math.h as sqrt() function declared in math.h header file. For e.g

#include <math.h>

secondly, if you read manual page of sqrt you will notice this line Link with -lm.

#include <math.h> /* header file you need to include */

double sqrt(double x); /* prototype of sqrt() function */

Link with -lm. /* Library linking instruction */

But application still says undefined reference to sqrt. Do you see any problem here?

Compiler error is correct as you haven't linked your program with library lm & linker is unable to find reference of sqrt(), you need to link it explicitly. For e.g

gcc -Wall -Wextra -Werror -pedantic test.c -lm
Achal
  • 11,821
  • 2
  • 15
  • 37
-1

I had the same issue, but I simply solved it by adding -lm after the command that runs my code. Example. gcc code.c -lm

Mohamed Mnete
  • 95
  • 2
  • 2