为什么 sqrt 函数对通过用户输入获取的值不起作用?

Gau*_*don 2 c sqrt

以下代码:

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

int main(void)
{
    long long int a;
    scanf("%lld", &a);
    printf("%lf", sqrt(a));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

给出输出:

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
Run Code Online (Sandbox Code Playgroud)

但是,如果我执行long long int a = 25;并删除scanf语句,或者只是执行sqrt(25),它们都可以工作(正确给出 output 5.000000)。

我检查了这个问题,但它是针对 C++ 并使用函数重载的,而 afaict C 没有函数重载(这就是为什么我们有sqrtf, sqrtsqrtl如果我没记错的话)。此外,无论我采用long long int还是double类型,上面的代码都失败了a。所以,这些问题可能是不相关的。
此外,关于其他链接问题,对于不断定义的值,我没有发生错误,而链接问题恰好是这种情况。

那是什么原因呢?为什么恒定值适用于sqrt,而可变用户输入值则无效?

Jon*_*art 5

就像评论中提到的一样,你还没有链接反对 libm因此sqrt在链接时未定义。

为什么恒定值适用于 sqrt,而可变用户输入值则无效?

因为 GCC 识别sqrt内置函数并且能够在编译时计算编译时常量的平方根,并放弃调用sqrt完全,从而避免了后续的链接器错误。

ISO C90 函数 ... sqrt, ... 都被识别为内置函数,除非-fno-builtin指定(或-fno-builtin-function为单个函数指定)。

如果您要添加-fno-builtin-sqrt,无论您传递给什么,您都会看到链接器错误sqrt