编译器允许弱符号函数,无需实现且无链接器错误

问题描述 投票:0回答:1

静态库声明带有弱符号的函数。

后来应用程序(不提供函数实现)静态链接该库,但不会生成链接器错误。

GCC 11.4 和 Clang 16 似乎都会出现这种情况。

这是在询问时发现的:

静态库调用未实现的弱函数时不会出现链接器错误

示例:

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-1ubuntu1~22.04) 11.4.0 上,这会成功生成应用程序可执行文件。

在库上运行

nm

但是,使用 GCC 9.4 的其他人却得到了

u weak_func

然后运行我的应用程序并出现分段错误。

这是正确的吗?感觉就像是无声的失败。

gcc linker clang static-libraries static-linking
1个回答
0
投票

这是正确的吗?感觉就像是无声的失败。

是的,这正在按预期工作:弱引用不会导致链接失败(也不会导致链接器从存档库中提取定义对象)。

然后运行我的应用程序并出现分段错误。

调用可选提供的函数的通常方法是:

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

如果 not 提供

weak_func
是您希望在链接时检测到的错误,则不要声明所需的函数
weak

在您的其他问题中您说:

当库被编译和安装时,它显然不知道我的应用程序。

您似乎误解了档案库需要了解有关您的应用程序的任何信息。它不会——只需删除

weak
属性,一切都会正常工作(TM)。

更准确地说,没有

weak
属性:

  • 您的存档库将编译并安装得很好
  • 如果您的应用程序在其他地方定义了该函数,则链接将成功并且库将调用您的函数
  • 如果您的应用没有定义该功能,链接将失败
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.