5

考虑以下代码:

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这里坏了,还是我在标准中遗漏了什么?

4

2 回答 2

4

您正在错误地阅读标准。C 中没有隐式函数声明之类的东西。它已被 C99 从语言中删除。

GCC 在看到看起来像隐式函数声明的错误构造时会发出警告。就标准而言,这是可以的。标准在这里需要诊断,警告就是诊断。你可以使用-Werror=implicit-function-declarationGCC 的标志来把它变成一个错误。

于 2013-02-10T16:44:23.480 回答
1

这在6.5.1 主要表达式的注释中有所介绍:

2 - 标识符是主要表达式,前提是它已被声明为指定对象(在这种情况下它是左值)或函数(在这种情况下它是函数指示符)。79)


79) 因此,未声明的标识符违反了语法。

5.1.1.3 诊断需要一个符合要求的实现来生成诊断消息,以响应函数调用表达式的语法违规,该函数调用表达式涉及一个未声明的标识符作为表示被调用函数的表达式。当然可以自由地继续编译程序,就好像标识符已以隐式intC89 样式声明一样。

必须参考约束 6.5.2.2p1 阅读第 6.5.2.2p5 段:

1 - 表示被调用函数的表达式应具有指向函数的类型指针,该函数返回void或返回数组类型以外的对象类型。

因此,如果“表示被调用函数的表达式”没有类型指向返回对象类型的函数的指针”,则它必须按事实(通过约束 6.5.2.2p1)具有类型“指向函数返回void的指针”,并且它6.5.2.2p5中的“否则”是否涵盖这种情况。也就是说,我在[方括号]中插入:

5 - 如果表示被调用函数的表达式具有指向返回对象类型的函数的类型指针,则函数调用表达式具有与该对象类型相同的类型,并且具有如 6.8.6.4 中指定的那样确定的值。否则,[即如果表示被调用函数的表达式具有指向函数返回的类型指针void,]函数调用具有类型void

这是一种需要特殊语言而void不是对象类型的情况;不是被调用函数表达式是或包含未声明标识符的许可。

于 2013-08-05T13:52:03.983 回答