我有2个文件 - main.c和main1.c。
main.c中:
#include <stdio.h>
#include <stdlib.h>
void foo(void)
{
}
int main(void)
{
foo();
}
main1.c:
void foo(int a, int b);
我使用gcc编译:
gcc main.c main1.c -o main
编译没有错误。如果函数原型默认具有外部链接,为什么这可能?不应该gcc给我一个错误,foo被重新定义了不同数量的参数? C标准在哪里描述了这种行为?
答案 0 :(得分:1)
嗯,这是因为main1.c中的void foo(int a, int b);
只是前向声明。什么都没有定义。
如果您将main1.c更改为:
void foo(int a, int b) {}
你会看到错误。
答案 1 :(得分:0)
首先阅读translation units。
问题是,每个源文件都是单独编译的,编译器对其他源文件一无所知,只知道它在当前源文件中看到的内容。直到链接器看到多个定义才会出错。
在main1.c
文件中,你甚至可以用两个参数调用 foo
函数(或编译器会抱怨),但这可能会导致 undefined行为在函数的实际定义中,因为它所期望的参数数量与实际调用中的参数数量不同。在你的情况下它可能不是那么糟糕,因为实际的函数没有参数。但是想想是否相反,实际的函数需要两个参数,你从另一个没有参数的翻译单元调用它,实际函数中这些参数的值是什么?
答案 2 :(得分:0)
这是因为链接器(将目标文件链接在一起)不能区分函数接受的参数。
\由于void foo(int a, int b);
没有创建新符号,只是通知编译器这样一个符号的存在,它不会抱怨十八。
如果您尝试两次创建该功能
void foo(int a, int b) {}
现在这将发出链接器错误,表示符号foo
已定义两次。