调用没有原型的C函数

时间:2011-10-26 14:34:10

标签: c function function-prototypes

我有一个调用函数的C文件(比如file1.cfun1(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的原型才能实现此目的?

2 个答案:

答案 0 :(得分:5)

根据情况和编译器,可能会发生一些事情:

  • 您收到编译错误。编译器抛出武器并拒绝生成目标文件。
  • 编译器将函数声明视为调用所暗示的并继续链接。它可能假设你知道你在函数参数方面做了什么。通常它也假定为int返回类型。几乎每个与我合作的编译器都会在执行此操作时发出警告。
  • 编译器将声明视为呼叫隐含但未链接。像上面一样,但链接器然后注意到你试图调用的隐含函数和你实际编写的函数是不同的并且死了。

你应该提供原型,无论如何。

答案 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,那么这些步骤都会被一个漂亮的界面隐藏。