其他分享
首页 > 其他分享> > C编译并链接指向未定义函数的指针

C编译并链接指向未定义函数的指针

作者:互联网

这段代码:

void undefined_fcn();
void defined_fcn() {}

struct api_t {
    void (*first)();
    void (*second)();
};
api_t api = {undefined_fcn, defined_fcn};

定义一个全局变量api,其中包含指向不存在函数的指针.然而,它编译,令我惊讶的是,与GCC绝对没有任何投诉的链接,即使是所有那些-Wall -Wextra -Werror -pedantic标志.

此代码是共享库的一部分.只有当我加载库时,在运行时它才会失败.如何在图书馆链接时检查我没有忘记定义任何功能?

更新:this question提到同样的问题,答案是一样的:-Wl, – no-undefined. (顺便说一句,我想这甚至可以标记为重复).但是,根据下面接受的答案,使用-Wl, – no-undefined时应该小心.

解决方法:

This code is part of a shared library.

这是关键.拥有共享库的全部目的是拥有一个“不完整”的共享对象,其中未定义的符号必须在主可执行文件加载它时解析,并与其链接的所有其他共享库进行解析.那时,运行时加载程序尝试解析所有未定义的符号;必须解析所有未定义的符号,否则可执行文件将无法启动.

你说你正在使用gcc,所以你很可能使用GNU ld.由于上述原因,ld将使用未定义的符号链接共享库,但无法链接可执行文件,除非针对可执行文件链接的共享库解析所有未定义的符号.因此,在运行时,预期的行为是期望运行时加载程序也成功解析所有符号;因此,运行时加载程序无法启动可执行文件的唯一情况将指示致命的运行时环境故障(例如,共享库被替换为不兼容的版本).

有一些选项可用于覆盖此行为. –no-undefined选项指示ld在链接共享库时报告未定义符号的链接失败,就像可执行文件一样.当通过gcc间接调用ld时,这变为-Wl, – no-undefined.

但是,您可能会发现这将是一个失败的主张.您最好希望共享库中的所有代码都不使用标准C或C库中的任何类.因为,猜猜怎么着? – 这些引用将是未定义的符号,您将无法链接您的共享库!

换句话说,这是你需要处理的必要的邪恶.

标签:static-assert,c,linker
来源: https://codeday.me/bug/20190823/1700231.html