我有这个C编译问题。
我花了很长时间才了解问题的根本原因。 虽然现在我已经截获了这个问题,但我不确定我是否完全低估了完整的C编译流逻辑。
我有两个导演:inc和src
在inc目录中,我有一个文件:test.h 在src目录中,我有两个文件:test.c和main.c
test.c文件实现了一个函数,让它调用test(),并且main.c文件调用这个test()函数。
我在test.h文件中声明了这个函数
现在,我只将这个test.h文件包含在main.c文件中,以便让main.c文件到"看到" test()函数的声明。
编译时:
g++ -o test.o -c test.c
g++ -o main.o -c main.c
g++ -o test test.o main.o
在上一个命令中,我收到错误的"未定义的引用' test'
调试此问题后,我发现test.c文件中缺少的test.h文件包含解决了这个问题。
换句话说,我需要在两个源文件中包含test.h文件 - main.c和test.c
我的问题是,为什么? 仅仅在main.c文件中包含头文件test.h文件是不够的,以便让它"参见"函数声明,在链接阶段,编译器将“知道”#34;将main.c文件中使用的test()函数与test.c文件中的实现相关联?
我认为test.h文件中test()函数的声明使它成为" extern"声明,因此它将通知编译器在链接阶段找到函数实现
答案 0 :(得分:1)
问题是因为你的原型与实现不匹配。
如果你要使用C编译器,由于错误的参数和返回值处理,你会得到有趣的运行时错误,因为生成的符号通常不包含参数信息。
使用C ++,编译器会生成依赖于参数类型的方法签名。因此,具有相同名称但不同参数的两个函数将产生两个不同的符号,因此链接器不会混淆它们。
所以修复你的原型,它会起作用......
答案 1 :(得分:0)
我不认为在main.c中添加test.h而在test.c中没有任何问题。请再次检查您的设置。
您可以在test.h
中声明该功能,并在test.h
中包含main.c
或在extern
本身中将该函数声明为main.c
。
在这两种方式中,链接器都必须完成查找test()
包含文件通常是将接口与实现分开。