Bal*_*laK 6 c function function-prototypes
从K&R Book on C,我收集到如果函数原型声明省略了参数(如int foo();
),关闭类型和参数检查,并且没有假设参数与旧版本的C兼容,因此它不会打破遗留代码.
但是下面的代码抛出了原型不匹配的编译错误:
#include <stdio.h>
void test();
int main(void) {
test(34.5f);
}
void test(float a) {
printf("%f\n", a);
}
Run Code Online (Sandbox Code Playgroud)
错误:
C:\***.c:7:6: error: conflicting types for 'test'
void test(float a) {
^
Run Code Online (Sandbox Code Playgroud)
有什么解释吗?
当函数被多次声明时,所有声明必须具有兼容类型(C11 6.2.7/2).在您的代码f
中声明两次 - 该定义也算作声明.
"兼容功能类型"的定义见C11 6.7.6.3/15:
要使两种函数类型兼容,两者都应指定兼容的返回类型.此外,参数类型列表(如果两者都存在)应在参数的数量和省略号终止符的使用中一致; 相应的参数应具有兼容的类型.如果一个类型具有参数类型列表而另一个类型由函数声明符指定,该函数声明符不是函数定义的一部分并且包含空标识符列表,则参数列表不应具有省略号终止符,并且每个参数的类型应为与应用默认参数促销产生的类型兼容.如果一个类型具有参数类型列表而另一个类型由包含(可能为空)标识符列表的函数定义指定,则两者应在参数数量上一致,并且每个原型参数的类型应与类型兼容这是因为默认参数促销应用于相应标识符的类型.(在确定类型兼容性和复合类型时,使用函数或数组类型声明的每个参数都被视为具有调整类型,并且使用限定类型声明的每个参数都被视为具有其声明类型的非限定版本.)
因此void test()
而且void test(float)
是不相容的.换句话说,在看到之后void test();
,任何原型必须仅使用默认参数促销未更改的类型.这些促销活动的float
变化double
.
我相信自第一个C标准以来一直如此.
wal*_*lyk -1
你已经告诉gcc
编译c11
代码,而不是像 K&R 那样。
我查看了这些-std=
选项,但没有一个是有用的。也许完全省略语言标准参数会有所帮助。或者将其指定为c89
.
在 c11 中,始终需要完整形状的原型。因此,第一次使用给出的函数具有parameter= (void)
。在 C++ 之前的版本中,这确实意味着“可能传递或不传递参数”。