为什么有可能在不同的文件中重新定义具有不同数量的参数的函数?

时间:2014-02-27 18:05:17

标签: c linkage function-prototypes

我有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标准在哪里描述了这种行为?

3 个答案:

答案 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已定义两次。