调用者/被调用者签名不匹配的情况下,gcc函数调用语义

3

我在gcc中发现了一些奇怪的东西,希望获得一些反馈,看它是一种特性还是怪癖。
基本上,我在func.c中定义了一个函数:

void f(int a, int b, FILE* f)  
{  
   ...  
   ...  
} 

没有相应的头文件,但是当我调用f(a,b)时,gcc没有给出任何警告,gdb显示f被三个参数调用? 为什么会这样?填充第三个参数的语义是什么。


如果你好奇的话,第三个参数可能是从其他地方留下的堆栈值,很可能没有意义(除非它恰好为NULL的0)。 - Chris Lutz
1个回答

4
如果 f() 没有在任何地方声明并且没有在当前编译单元中定义,编译器会假定 f() 返回 int 并且可以接受任意数量的参数。
我知道这很奇怪,但在旧日子里,这可能是减少必须包含的头文件数量,从而加快编译速度的一种方法。

+1 这是 C89 的一个错误特性,为了向后兼容而存在,但在 C99 中被移除了(我认为)。如果你增加警告级别,GCC 会在出现这种情况时发出警告。 - Chris Lutz
gcc 4.4 使用 -std=c99 编译时默认会发出隐式声明的警告(我没有提供任何额外的警告标志)。 - bstpierre
我没想到它背后有一个有趣的历史。很喜欢它。感谢所有的输入。我已经将警告调到最高了。 - Kabira K
1
这里有一点错误。编译器并不会“假设f可以接受任意数量的参数”。那将是一个可变参数函数,必须在参数列表中使用...进行原型声明。相反,编译器假定您知道自己在做什么,并使用确切数量和类型的参数(在默认提升之后)调用它所需的函数。如果您违反了这个约定,您的程序就会出现未定义的行为。 - R.. GitHub STOP HELPING ICE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接