我正在寻找一种在声明函数时产生链接器错误的方法 但未在导出的类中定义。这是一个简单的例子 说明了问题:
test.h:
#define DLLEXPORT __attribute__((__visibility__("default")))
class DLLEXPORT CLASS_A {
public:
CLASS_A();
~CLASS_A();
void withdefinition();
void nodefinition();
};
TEST.CPP:
#include "test.h"
CLASS_A::CLASS_A() {}
CLASS_A::~CLASS_A() {}
void CLASS_A::withdefinition() {}
生成文件:
CFLAGS = -Wall -Wextra -fvisibility=hidden -fvisibility-inlines-hidden -fPIC
LDFLAGS = -Wl,--no-undefined
top: test.so
test.o: test.cpp test.h Makefile
g++ $(CFLAGS) -c $< -o $@
nm -C test.o
test.so: test.o
g++ -shared $(CFLAGS) $(LDFLAGS) $< -o $@
nm -C test.so
我从“nm test.o”看到的输出如下:
nm -C test.o
0000000000000014 T withdefinition()
0000000000000000 T CLASS_A::CLASS_A()
0000000000000000 T CLASS_A::CLASS_A()
000000000000000a T CLASS_A::~CLASS_A()
000000000000000a T CLASS_A::~CLASS_A()
函数“withdefinition()”生成外部定义,而函数“nodefinition()”根本不生成符号。理论上,如果test.cpp的编译可以为“nodefinition”生成未定义的符号,则后续的链接命令会抱怨未定义的符号。不幸的是,只有在代码中显式调用“nodefinition()”时才会发生这种情况。这是一个在重构过程中通常会出现的错误,如果可以尽早检测到它会有所帮助 - 是否有一种简单的方法可以使用gcc工具链自动执行此操作?
答案 0 :(得分:1)
声明但未定义的(非虚拟)函数在编译的代码中不产生任何跟踪。这是设计的。你无法改变它,因为这样的改变绝对会破坏一切。
想象一下每个功能,每个课程,每一个数据,你在标准include
文件中没有任何东西,你不会使用,不关心和不关心。甚至知道它存在,在你的编译代码中留下一个符号。
答案 1 :(得分:0)
由于编译器实际上并不知道您在哪里定义哪些函数,因此编译器/链接器无法执行此任务。
请注意,在编译阶段可能存在可能存在名为nodefinition
的函数的知识,因此只有在实际使用该函数时才会保留此信息。
如果您有严格的&#34; x.h&#34;你可以使用clang分析框架编写一些(或找到其他人已经编写的)代码分析工具。和&#34; x.cpp&#34;关系,因此没有在&#34; x.h&#34;中声明的功能永远在另一个文件中定义,而不是&#34; x.cpp&#34; (或#34; x.cpp&#34所包含的文件;)。但是如果在其他地方允许实现,那么它只能检测链接器实际需要该函数的时间。
当然,在大多数情况下,代码审查也应该抓住这类问题。