Undefined reference to sqrt (or other mathematical functions)
Asked Answered
O

5

91

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.

Overscore answered 9/3, 2011 at 16:32 Comment(4)
Which complains, the linker or the compiler? If you can post the exact error that'd probably clear things up.Myrtice
compiler write this complain, problem is, that app don't even built...Overscore
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.Foredeck
Related: #1034398Moray
D
126

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.

Duncandunce answered 9/3, 2011 at 16:34 Comment(8)
@Duncandunce : and in the case of µClibc for csqrt?Emeldaemelen
@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.Duncandunce
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).Labialize
Good pointer @KevinBullaughey I also had to move another link option to the back (-lpthread).Aeromechanics
Also note that -lm must come last! See here: Undefined reference to sin.Antispasmodic
@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 :-)Duncandunce
@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.Antispasmodic
@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.Duncandunce
H
32

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.

Hummel answered 9/3, 2011 at 16:36 Comment(0)
A
4

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
Artwork answered 28/7, 2019 at 5:39 Comment(0)
A
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
Anthe answered 9/7, 2017 at 20:1 Comment(1)
Please, share the reason of "pthread".Oas
B
0

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

Beanpole answered 5/2, 2017 at 21:32 Comment(1)
How is this different from the other answers that were posted several years ago?Vilmavim

© 2022 - 2024 — McMap. All rights reserved.