gcc 编译器允许没有实现和没有链接器错误的弱符号函数

vq8itlhq  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(180)

一个静态库声明了一个带有弱符号的函数。
稍后,应用程序(不提供函数实现)静态链接库,但不会生成链接器错误。
这似乎发生在GCC 11.4和Clang 16中。
这是在询问时发现的:
No linker error when static library calls weak function with no implementation
范例:
lib_file.h:

__attribute__((weak)) int weak_func(int x, int y);

void func();

字符串
lib_file.c:

#include "lib_file.h"

void func()
{
    weak_func(6, 7);  // Want this to call function implemented in my app
}


app.c:

#include "./lib_file.h"

int main() 
{
    func();
    return 0;
}


编译和链接:

gcc -c -o libfunc.o lib_file.c
ar rcs libfunc.a libfunc.o
gcc app.c -lfunc -L./


在我的系统gcc(Ubuntu 11.4.0- 1ubuntu 1 ~22.04)11.4.0上,这成功地生成了应用程序可执行文件。
在库上运行nm
x1c 0d1x的数据
然而,其他使用GCC 9.4的人得到了u weak_func
然后我运行我的应用程序,得到一个分段错误。
是这样吗?感觉像是无声的失败。

rks48beu

rks48beu1#

是这样吗?感觉像是无声的失败。
是的,这是按预期工作的:弱引用 * 不会 * 导致链接失败(也不会导致链接器从归档库中拉取定义对象)。
然后我运行我的应用程序,得到一个分段错误。
调用可选函数的常用方法是:

void func()
{
  if (&weak_func != NULL)
    weak_func(6, 7);  // Call weak_func if one has been provided.
}

字符串
如果 not providing weak_func是你希望在链接时检测到的错误,那么不要声明必需的函数weak
在你的另一个问题中,你说:
当库被编译和安装时,它显然不知道我的应用程序。
您似乎误解了归档库需要了解您的应用程序的任何信息,它 * 并不 * --只需删除weak属性,一切就可以正常工作了(TM)。
更准确地说,如果没有weak属性:

  • 您的存档库将编译和安装刚刚好
  • 如果您的应用在其他地方定义了该函数,则链接将成功,并且库将调用您的函数
  • 如果您的应用未定义该函数,则链接将失败

相关问题