The following code:
#include <stdio.h>
#include <math.h>
int main(void)
{
long long int a;
scanf("%lld", &a);
printf("%lf", sqrt(a));
return 0;
}
gives output:
source_file.c: In function ‘main’:
source_file.c:9:5: warning: ignoring return value of ‘scanf’, declared with attribute warn_unused_result [-Wunused-result]
scanf("%lld", &a);
^
/tmp/ccWNm2Vs.o: In function `main':
source.c:(.text.startup+0x65): undefined reference to `sqrt'
collect2: error: ld returned 1 exit status
However, if I do long long int a = 25;
and delete the scanf
statement, or simply do sqrt(25)
, both of them work (correctly give output 5.000000
).
I checked this question, but it is for C++ and uses function overloading, whereas afaict C does not have function overloading (that's why we have sqrtf
, sqrt
, sqrtl
if I'm not wrong). Moreover, the above code fails whether I take long long int
or double
type of a
. So, the questions are probably not related.
Also, regarding the other linked question, the error did not occur for me for constantly defined values, which instead happens to be the case with the linked question.
What is the reason then? Why would a constant value work for sqrt
, while a variable user input value won't?
Like was mentioned in the comments, you haven't linked against libm
so sqrt
is undefined at link-time.
Why would a constant value work for
sqrt
, while a variable user input value won't?
Because GCC recognizes sqrt
as a builtin function and is able to evaluate the square root of a compile-time constant at compilation time, and forgoes the call to sqrt
altogether, thus avoiding the subsequent linker error.
The ISO C90 functions ...
sqrt
, ... are all recognized as built-in functions unless-fno-builtin
is specified (or-fno-builtin-
function
is specified for an individual function).
If you were to add -fno-builtin-sqrt
, you would see the linker error regardless of what you pass to sqrt
.