Why Do Some Machines Require '-lm' for Compiling C Programs While Others Don't?

Join the discussion
Ask a follow-up here, or get your own question answered by working scientists, mathematicians and engineers — people, not an autocomplete.
Real named experts · corrections over time · the nuance an AI answer skips
9 replies · 4K views
Ja4Coltrane
Messages
224
Reaction score
0
So I am trying to write a program in C including simple mathematical functions given in math.h. In particular, I want sin(), cos() and pow(). Now when I try to compile (using gcc), I get this error (using powf()):

Undefined first referenced
symbol in file
powf /var/tmp/ccbfbDve.o
ld: fatal: Symbol referencing errors. No output written to a.out
collect2: ld returned 1 exit status

Any help?
 
Physics news on Phys.org
Could you post your code?
 
I am on an ssh with a linux. I don't know what it means to link -lm. My actual code is way too long so I'll send an example which gives the same problem:

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

main ()
{
printf("%f\n", powf(2.0, 3.0));
}
 
"ld:" indicates a linking error, not a compilation error. There is nothing wrong with your code, you just aren't linking to the math library. You need to fix your makefile.
 
The compiler converts your .c file into a binary .obj file
The linker then converts this into an executable (a.out on linux) including any other system code to do things like maths functions.
GCC calls the linker automatically so you might never see the link command.
For various technical reasons the maths lib is special (eg. you might have different version for speed or precision) and so you have to tell GCC to use it explicity.

Basically just type the same gcc command line as before, but put '-lm' on the end of the line.
 
mgb_phys said:
The compiler converts your .c file into a binary .obj file
The linker then converts this into an executable (a.out on linux) including any other system code to do things like maths functions.
GCC calls the linker automatically so you might never see the link command.
For various technical reasons the maths lib is special (eg. you might have different version for speed or precision) and so you have to tell GCC to use it explicity.

Basically just type the same gcc command line as before, but put '-lm' on the end of the line.

Yes, I learned this when I took a C programming class and was very confused when my code compiled fine in windows but would return an error on Solaris. It compiled fine using g++. The CS professor pointed out that you need to use the -lm switch to properly link the math library in gcc.
 
vociferous said:
Yes, I learned this when I took a C programming class and was very confused when my code compiled fine in windows but would return an error on Solaris. It compiled fine using g++. The CS professor pointed out that you need to use the -lm switch to properly link the math library in gcc.

Not necessarily true. For instance, a quick straw poll of the five machines in the room I'm sitting in right now (an iBook G4, a MacBook Pro, two Core2 Duo desktops, and a rather menacing Itanium-toting thing, all running either OS X or Debian) shows me that three of them -- the macs and one of the Core2 Duos -- will compile quite happily without passing '-lm' upon linking. All run various versions of gcc 3.x or 4.x.

I've never quite been able to figure out if there's a good reason why some compilers on some machines can automagically handle '-lm' linking, whereas others can't. If anyone can point out why this is so I'd be grateful.
 
Last edited:
Code:
gcc mfile.c -o myfile -lm
The -lm part means go to /lib and find a shared library name libm. Link any unresolved symbols against it.
 
shoehorn said:
Not necessarily true. For instance, a quick straw poll of the five machines in the room I'm sitting in right now (an iBook G4, a MacBook Pro, two Core2 Duo desktops, and a rather menacing Itanium-toting thing, all running either OS X or Debian) shows me that three of them -- the macs and one of the Core2 Duos -- will compile quite happily without passing '-lm' upon linking. All run various versions of gcc 3.x or 4.x.

I've never quite been able to figure out if there's a good reason why some compilers on some machines can automagically handle '-lm' linking, whereas others can't. If anyone can point out why this is so I'd be grateful.
On the machines that work, there is probably an environment variable (something like CFLAGS or CPPFLAGS) that implicitly passes the '-lm' flag to gcc.