Undefined reference to `sin`
CMathLinker ErrorsUndefined ReferenceC Problem Overview
I have the following code (stripped down to the bare basics for this question):
#include<stdio.h>
#include<math.h>
double f1(double x)
{
double res = sin(x);
return 0;
}
/* The main function */
int main(void)
{
return 0;
}
When compiling it with gcc test.c
I get the following error, and I can't work out why:
/tmp/ccOF5bis.o: In function `f1':
test2.c:(.text+0x13): undefined reference to `sin'
collect2: ld returned 1 exit status
However, I've written various test programs that call sin
from within the main
function, and those work perfectly. I must be doing something obviously wrong here - but what is it?
C Solutions
Solution 1 - C
You have compiled your code with references to the correct math.h header file, but when you attempted to link it, you forgot the option to include the math library. As a result, you can compile your .o object files, but not build your executable.
As Paul has already mentioned add "-lm
" to link with the math library in the step where you are attempting to generate your executable.
> Why for sin()
in <math.h>
, do we need -lm
option explicitly; but,
> not for printf()
in <stdio.h>
?
Because both these functions are implemented as part of the "Single UNIX Specification". This history of this standard is interesting, and is known by many names (IEEE Std 1003.1, X/Open Portability Guide, POSIX, Spec 1170).
This standard, specifically separates out the "Standard C library" routines from the "Standard C Mathematical Library" routines (page 277). The pertinent passage is copied below:
> Standard C Library
>
> The Standard C library is automatically searched by
> cc
to resolve external references. This library supports all of the
> interfaces of the Base System, as defined in Volume 1, except for the
> Math Routines.
>
> Standard C Mathematical Library
>
> This library supports
> the Base System math routines, as defined in Volume 1. The cc
option
> -lm
is used to search this library.
The reasoning behind this separation was influenced by a number of factors:
- The UNIX wars led to increasing divergence from the original AT&T UNIX offering.
- The number of UNIX platforms added difficulty in developing software for the operating system.
- An attempt to define the lowest common denominator for software developers was launched, called 1988 POSIX.
- Software developers programmed against the POSIX standard to provide their software on "POSIX compliant systems" in order to reach more platforms.
- UNIX customers demanded "POSIX compliant" UNIX systems to run the software.
The pressures that fed into the decision to put -lm
in a different library probably included, but are not limited to:
- It seems like a good way to keep the size of libc down, as many applications don't use functions embedded in the math library.
- It provides flexibility in math library implementation, where some math libraries rely on larger embedded lookup tables while others may rely on smaller lookup tables (computing solutions).
- For truly size constrained applications, it permits reimplementations of the math library in a non-standard way (like pulling out just
sin()
and putting it in a custom built library.
In any case, it is now part of the standard to not be automatically included as part of the C language, and that's why you must add -lm
.
Solution 2 - C
I still have the problem with -lm
added:
gcc -Wall -lm mtest.c -o mtest.o
mtest.c: In function 'f1':
mtest.c:6:12: warning: unused variable 'res' [-Wunused-variable]
/tmp/cc925Nmf.o: In function `f1':
mtest.c:(.text+0x19): undefined reference to `sin'
collect2: ld returned 1 exit status
I discovered recently that it does not work if you specify -lm
first. The order matters. You must specify -lm
last, like this:
gcc mtest.c -o mtest.o -lm
That links without problems.
So, you must specify the libraries at the end.
Solution 3 - C
You need to link with the math library, libm:
$ gcc -Wall foo.c -o foo -lm
Solution 4 - C
I had the same problem, which went away after I listed my library last: gcc prog.c -lm