考虑以下代码:
int main (void) {
int i = xyzzy();
return i;
}
int xyzzy (void) {
return 42;
}
现在,虽然 for 的原型xyyzy
在使用时是未知的,但这在 c89 模式下有效,因为没有原型的函数的默认返回类型是int
隐式函数原型和实际函数兼容。
而且,事实上,如果您将函数的返回类型更改为float
,您会得到(如预期的那样):
testprog.c:6: error: conflicting types for 'xyzzy'
testprog.c:2: error: previous implicit declaration of 'xyzzy' was here
因为隐式原型和实际函数不再匹配。
编译的原始代码gcc --std=c89 --pedantic -Wall -Wextra
只给了我警告:
testprog.c: In function 'main':
testprog.c:2: warning: implicit declaration of function 'xyzzy'
这是意料之中的,因为 c89 有这样的说法3.7.1 Function definitions
:
extern int max(int a, int b) { ... }:这
extern
是存储类说明符,int
也是类型说明符(每个都可以省略,因为它们是默认值)。
并在3.3.2.2 Function calls
:
如果函数调用中带括号的参数列表之前的表达式仅包含一个标识符,并且如果该标识符没有可见的声明,则该标识符被隐式声明,就好像在包含函数调用的最里面的块中,声明extern整数标识符();出现了。
因此,在声明之前使用函数肯定会导致创建默认原型。
然而,这两个短语在 c99 中都被删除了,而是在6.5.2.2 Function calls
(我的粗体)中找到:
如果表示被调用函数的表达式具有指向返回对象类型的函数的类型指针,则函数调用表达式具有与该对象类型相同的类型,并且具有如 6.8.6.4 中指定的那样确定的值。否则,函数调用的类型为 void。
我理解它的意思是,如果在您尝试调用函数时没有看到声明,那么它会隐式声明为void
返回类型。
然而,当使用 编译时gcc --std=c99 --pedantic -Wall -Wextra
,我得到关于隐式声明的相同警告。
c99 不应该将该函数隐式声明为返回void
吗?如果有的话,我会预料到一个previous implicit declaration
错误,类似于我尝试将其重新声明为时得到的错误float
。
gcc
这里坏了,还是我在标准中遗漏了什么?