好的,所以标准中的任何地方都没有说,仅仅因为您 #include <math.h>
还将链接到标准数学库……事实上,这不会发生。
您必须链接到 libm 才能使用标准数学库,如下所示:
cc -o foo foo.c -lm
^^^^
标记的选项实际上用于链接器步骤,没有它,无论您是库中的函数作为返回值还是使用它来实际调用函数,都没有链接。
外部符号通过明确指定档案/对象/库或在系统/环境的情况下通过动态链接在运行时延迟链接来解决。
在支持动态链接、弱链接、惰性链接等的环境中,不能保证引用将永远被解析。对于解决方案,必须遍历执行路径。
让我们说它是。尽管如此,您的客户端还需要在链接时或在运行时为支持它的环境提供解决sinf的链接路径。
重点:
客户端用户可以使用任何方式将符号解析为他们认为合适的地址;所以,事实上,没有办法保证你的客户端会链接到标准库并且会解析到系统库sinf。您唯一知道的是,如果执行了该路径;它会导致一个可以使用 sinf 链接查找的地址,或者对于不需要在链接时解析符号的环境,它会毫不客气地崩溃。
更新/澄清:
澄清一下,如果将 sinf 用作变量;那么它需要被解析,但仍然不能保证当客户端代码在他们完成链接步骤时解析符号时,他们将根据数学库解析它。如果我们谈论的是保证。
现在实际上来说,如果客户端链接到标准数学库并且没有提取他们可以的任何覆盖(我在上面指出),那么是的,该符号将被解析为需要与标准库的链接(或者静态或动态)
我最初的回答有点“拘谨”,对此我深表歉意,因为我们谈论的是标准和保证,因此具有讽刺意味。例如,没有什么可以阻止客户端简单地执行以下操作:
富.c:
#include "my_interface.h"
...
myfunc func = get_the_func();
printf("%f\n", func(0.0f));
第一遍编译:
cc -o foo foo.c
得到一个sinf
未解决的错误,因此客户端编辑她的源文件:
富.c:
#include "my_interface.h"
...
void * sinef = NULL;
myfunc func = get_the_func();
printf("%f\n", func(0.0f));
现在你有一个完全解决但很好崩溃的程序;