我有一个调用函数的C文件(比如file1.c
)
fun1(1,b)
。
此函数fun1(int a,int b)
驻留在另一个C文件(例如file2.c
)中,但其原型未包含在头文件中(例如file2.h
)。
file2.h
中包含file1.c
。
我的问题是,如果我从fun1(a,b)
拨打file1.c
,它会通过将控制传递给file2.c
中的函数定义来实现吗?或者是否会发生异常或预期的行为是什么?
我是否必须在fun1(int a, int b)
中提供file2.h
的原型才能实现此目的?
答案 0 :(得分:5)
根据情况和编译器,可能会发生一些事情:
你应该提供原型,无论如何。
答案 1 :(得分:3)
预期的行为是,如果目标文件链接在一起,您的函数将被调用。任何未声明的函数都被假定为一个外部函数,它返回一个用于编译目的的整数,以及一个外部符号(到目标文件)以便链接。我会给你具体的例子:
foo.c:
void foo(const char *name) {
printf("foo called with %s\n", name);
}
bar.c:
void bar(int a) {
printf("bar called with %d\n", a);
}
main.c:
int main(int argc, char *argv[]) {
foo("Hello");
bar(5);
return 0;
}
使用gcc:
编译目标文件gcc -fno-builtin -ansi -c -o foo.o foo.c
gcc -fno-builtin -ansi -c -o bar.o bar.c
gcc -fno-builtin -ansi -c -o main.o main.c
这些不应产生任何警告或错误
现在将它们链接在一起:
gcc -o progy main.o bar.o foo.o
请注意,我使用gcc链接二进制文件,但这相当于:
ld -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o progy /usr/lib64/crt1.o /usr/lib64/crti.o /usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.1/crtbegin.o main.o foo.o bar.o -lc -L/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.1 -lgcc -lgcc_s /usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.1/crtend.o /usr/lib64/crtn.o
在我的Linux 64位平台上。 (GCC实际上像这样运行LD来进行链接)
使用您的C编译器(在我的情况下为gcc)进行链接将确保无论您的构建目标平台是什么,都可以正确调用链接器。如果您使用IDE,那么这些步骤都会被一个漂亮的界面隐藏。