为何调用参数数量不匹配的C语言函数时无编译警告?
问题:为何传入参数数量不匹配的函数调用能正常编译?
我误调用了参数数量少于其原型定义的函数,代码编译时未产生警告,因此开展了如下实验:
实验代码
#include <stdio.h> void main() { printf("1 param %d \n",f(1)); printf("2 params %d \n",f(2,7)); printf("3 params %d \n",f(7,8,9)); } int f(int a, int b) { return (a+b); }
使用gcc try.c编译后无警告,运行结果为:
1 param -557760119 2 params 9 3 params 15
我的问题是:为何调用需要两个参数的f()函数时,传入1个或3个参数都能正常编译?
解答
这是因为C89标准允许函数隐式声明,你的代码刚好触发了这个旧规则:
- 在
main里调用f时,f还没有被声明或定义,编译器会自动生成一个隐式声明:默认返回int类型,且接受任意数量、任意类型的参数(调用时参数会做默认提升,比如char转int、float转double)。 - 当后续遇到
f的实际定义int f(int a, int b)时,由于返回类型和隐式声明一致(都是int),C89标准认为这种情况合法,不会触发参数数量不匹配的警告。
再补充解释下运行结果的逻辑:
- 传入2个参数时,完全匹配函数定义,计算
2+7得到9,结果正常。 - 传入1个参数时,函数需要两个
int参数,第二个参数会从栈上的随机垃圾数据中读取,所以返回值是1加上一个不确定的数值,也就是你看到的随机负数。 - 传入3个参数时,函数只会读取栈上的前两个参数(7和8)相加得到15,第三个参数9会被直接忽略,因为函数定义只处理两个参数。
如果用C99及以后的标准编译(比如执行gcc -std=c99 try.c),编译器就会报错——因为C99已经废除了隐式函数声明的规则,要求必须先声明或定义函数才能调用。
内容的提问来源于stack exchange,提问作者RDF
相关产品推荐
相关产品推荐

