gpt4 book ai didi

GCC 内置函数 - 2003 年与 2019 年的行为

转载 作者:行者123 更新时间:2023-12-01 23:36:55 27 4
gpt4 key购买 nike

Brian Gough 在《GCC 简介》一书的第 14 页,作者想显示一个链接器错误,因为没有为 gcc 提供 libm 库,其中函数 sqrt 的代码位于:

$ gcc -Wall calc.c -o calc
/tmp/ccbR6Ojm.o: In function ‘main’:
/tmp/ccbR6Ojm.o(.text+0x19): undefined reference to ‘sqrt’

calc.c 文件(调用函数sqrt 的地方)是这样的:

#include <math.h>
#include <stdio.h>
int main (void)
{
double x = sqrt (2.0);
printf ("The square root of 2.0 is %f\n", x);
return 0;
}

这本书是 2003 年的。在我当前的 Ubuntu Linux 18 上,我无法重现链接错误:它链接并工作,打印正确的结果:

$ ./calc
1.414214

我发现 ldd calc 不会在运行时调用 libm.so 共享库。当然这里也不涉及静态库libm.a。那么gcc是如何处理函数sqrt的呢?我发现在这种情况下它使用 sqrt GCC 内置函数。它的代码在编译时插入到 calc.o 目标文件中。所以没有“ undefined reference ”错误。

第一个问题:这就是整个故事,还是我遗漏了什么?

第二个问题:为什么这种关于 GCC 内置函数的行为在 2003 年(本书撰写时)和现在之间变化如此之大? (实际上使整个示例无效,在我看来)

第三个问题:为什么作者做他的例子(例如$ gcc -Wall calc.c -lm -o cal)暗示静态库将使用 libc.a,而实际上在 Linux 中该语法调用动态库 libm.so?这是特定于 Linux 而不是 GNU GCC 吗?我错过了什么?

最佳答案

我认为这是由于优化了一个常量值。现代 GCC 可以计算 sqrt (2.0) 的精确值。如果你强制它不使用 -fno-builtin 的内置函数,它仍然会链接失败。此外,如果您稍微更改代码以使 sqrt() 的参数不是文字,它将无法链接:

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

double t = 2.0;

int main (void)
{
double x = sqrt (t);
printf ("The square root of 2.0 is %f\n", x);
return 0;
}

这会产生链接错误:

> gcc -o test test.c              
/usr/bin/ld: /tmp/ccLjHnQx.o: in function `main':
test.c:(.text+0x11): undefined reference to `sqrt'
collect2: error: ld returned 1 exit status

关于你的第三个问题,-lm 并不意味着静态库,AFAIK。

关于GCC 内置函数 - 2003 年与 2019 年的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56372037/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com