【问题标题】:Why does sqrt function not work for values taken through user input? [duplicate]为什么 sqrt 函数不适用于通过用户输入获取的值? [复制]
【发布时间】:2019-04-01 09:13:28
【问题描述】:

以下代码:

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

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

给出输出:

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

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

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

那是什么原因呢?为什么常量值对sqrt 有效,而可变的用户输入值却不行?

【问题讨论】:

  • 你有链接到-lm 例如gcc -Wall test.c -lm 吗?
  • 显示你的确切构建命令和 gcc 版本
  • 另外你应该-std=c99(或更高版本,例如-std=c11),因为使用long long
  • @M.M -Wall -lm -std=gnu99 -O2 -o a.out source_file.c 我也试过-Wall -lm -o a.out source_file.c 没有成功。
  • @GaurangTandon -lm 必须在最后,正如 Achal 所建议的那样

标签: c sqrt


【解决方案1】:

就像 cmets 中提到的那样,您尚未链接到 libm,因此 sqrt 在链接时未定义。

为什么常量值适用于sqrt,而可变的用户输入值不起作用?

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

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

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

【讨论】:

    【解决方案2】:

    stdlib.hstdio.h 中的函数在libc.so(或libc.a 用于静态链接)中有实现,默认链接到可执行文件(就像指定了-lc)。

    可以使用-nostdlib-nodefaultlibs 选项指示GCC 避免这种自动链接。

    math.h 中的函数在libm.so(或libm.a 用于静态链接)中有实现,默认情况下不链接libm。

    基本上,C++ 运行时libstdc++ 需要libm,所以如果你用 GCC (g++) 编译 C++ 程序,你会自动得到 libm 链接。

    【讨论】:

      猜你喜欢
      • 2018-09-28
      • 1970-01-01
      • 2018-01-14
      • 2011-04-01
      • 1970-01-01
      • 2021-05-05
      • 1970-01-01
      • 2015-07-30
      • 2021-09-11
      相关资源
      最近更新 更多