我正在编写C大学项目,偶然发现了一些我不理解的编译器行为。
在这个文件http://code.google.com/p/openu-bsc-maximveksler/source/browse/trunk/20465/semester/tasks/maman14/alpha/maman14/assembler/phaseOne.c?r=112中,我添加了对名为freeAsmInstruction()的函数的调用。此函数在名为lineParser.c的文件中定义,但我没有更新匹配的lineParser.h头文件以包含此函数声明。
为什么这段代码会编译?我希望gcc无法编译phaseOne.c,直到使用freeAsmInstruction()的声明更新正确的lineParser.h。
我很感激解释。
谢谢你, 马克西姆
答案 0 :(得分:3)
GCC编译器假设一个特定的默认函数签名。要获得有关此的警告,请使用-Wall标志进行编译:
gcc -Wall -c phaseOne.c
这会给你一个警告:
phaseOne.c:2: warning: implicit declaration of function 'your func here'
除非你有充分的理由,否则你应该总是使用-Wall标志进行编译,也可能使用其他警告标志。
答案 1 :(得分:1)
未定义的函数不会自动出错;编译器将它们带到一个默认原型,然后当你的代码最终被链接时,如果有正确名称的东西将被使用。但是,如果默认原型不是你的函数实际所具有的,那么它的参数将被错误地设置(想想把方形钉子钉成圆孔);后果将是不可预测的。
在大多数情况下,您应该告诉编译器将此类情况视为错误。例如,在gcc上,将-Wall -Werror
添加到每个编译行,或者将它们添加到典型Makefile中的CFLAGS。
答案 2 :(得分:-1)
我刚刚在两个单独的文件中编写了一个示例程序:
<强> a1.c 强>
#include <stdio.h>
int main() {
// using the external object
testing();
return 0;
}
调用a2.c中存在的函数
void testing() {
printf("temp\n");
}
然后我所做的就是使用以下命令编译它:
$ gcc a1.c a2.c -o a1
并工作
实际上,在编译文件时,您是否在编译步骤中包含了另一个C文件(lineParser.c
)以与您的ParseOne.c
文件一起进行解析?
在这种情况下,我理解的是,gcc
实际上会解析相关C文件(或obj文件)中的所有符号,并在要创建的最终目标文件中适当地替换它们。
希望这有帮助。