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?
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 forprintf()
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 pressures that fed into the decision to put -lm
in a different library probably included, but are not limited to:
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
.