You are not logged in.
i'm getting an error when compiling anything with sqrt() from standard math.h. consider the simple sample code:
#include <math.h>
#include <stdio.h>
int main() {
double number, squareRoot;
printf("Enter a number: ");
scanf("%lf", &number);
// computing the square root
squareRoot = sqrt(number);
printf("Square root of %.2lf = %.2lf", number, squareRoot);
return 0;
}
every time i try to compile this with gcc sqr.c
i get the following error:
/usr/bin/ld: /tmp/ccguBUNA.o: in function `main':
sqr.c:(.text+0x50): undefined reference to `sqrt'
collect2: error: ld returned 1 exit status
Am i going insane?
Offline
You have to add -lm to your build command to link the math library.
aka Tamaranch: https://gitlab.xfce.org/Tamaranch
Offline
that works, but i never had to do that...
thing is... i deleted the project and recoded it, since it was a small enough project, and it worked without the -lm. i thought that this was because I copied part of the code from my notes, that was in a non simple text file, and probably that caused the issue. But it gets weirder, if i pass a value to sqrt, it works. if i pass a variable it fails...
works:
printf("%lf ",sqrt(25));
Fails compiling:
double value = 25;
printf("%lf ",sqrt(value));
Thanks for your reply!
Last edited by quimkaos (2022-03-29 14:57:02)
Offline
It "works" when you give a constant literal value to sqrt only because compilers are now pretty smart. As the only math function used in the code can be evaluated to a constant at compile-time, the compiler does that for you and eliminates it from the code. So there is no call to a "sqrt" function in the compiled code, and thus no need to link to the math library to provide a sqrt function. The compiler itself (essentially) edits "printf("%lf ",sqrt(25));" and replaces it with "printf("%lf ",5.0);". But it can't do such a replacement when you take the sqrt of a variable, as the outcome cant be precalculated at compile-time.
You also may not need to explicitly specify -lm on the compiler line if you are using another library that itself requires the math library (and quite a few do).
edit: "constant" isn't technically the correct term here. What's relevant is that it was a 'real literal'.
Last edited by Trilby (2022-03-29 16:37:30)
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
If you throw enough Os against it, #3 will still compile.
(Actually -O1 will do)
Online
thanks for the explainer
my question now is, is math.h the only library that needs this explicit linking?
since i'm using Clion and it uses CMake i'm going to have to remember to add target_link_libraries(output m) every time i use math.h
every tutorial, every video, misses this issue, maybe with the exception of the book "C how to program" by Deitel & Deitel, that has a reference, in really tiny whinny letters, that in Linux/gcc you need the -lm. Looks like i'm having a bad day, spent half a day running around my own tail ...
p.s. I understand the meaning of literal, the value it self not the variable/constant: string literal, integer literal...
Offline
You need to link whatever library you need - always.
If you use c++ (g++ -o test test.cpp) you won't have to pass libm, because it's linked by libstdc++, but for C, linking libc.so, you have to.
Online
Thank you!
Offline
If your function does not use any arguments, you should not declare it to use an arbitrary amount of arguments, but explicitly declare it to take no arguments:
int main(void) {
...
}
Inofficial first vice president of the Rust Evangelism Strike Force
Offline
[...] my question now is, is math.h the only library that needs this explicit linking?[...]
Good that the issue is solved! Out of curiosity, I looked up and it's been like this since glibc version 2.0: https://sourceware.org/git/?p=glibc.git … HEAD#l6662
Behemoth, wake up!
Offline