在C89标准中,'旧式'函数定义中函数名的作用域是什么?

3
以下的C89代码是否合法?
void f(a)
char a[sizeof &f];
{
}

我的想法是,是的,因为在任何块作用域之外声明的标识符的作用域从声明符的结束处立即开始,并延伸到翻译单元的结尾。 因此,'f'的作用域包括声明列表。

"gcc -pedantic -Wall"接受它。 "clang -pedantic -Wall"拒绝它,lcc也是如此。

1个回答

2

来自C90标准(我强调)

(C90, 6.1.2.1) "结构、联合和枚举标签的作用域始于在声明该标签的类型说明符中出现标签之后。每个枚举常量的作用域始于其定义的枚举器在枚举列表中出现之后。任何其他标识符的作用域始于其声明符完成之后。"

所以对我来说,这也是一个有效的函数声明。

编辑:魔鬼在细节中(单词完成),经过再次思考,我认为它不是一个有效的函数声明,因为在void f(a)之后声明符没有完成。

void f(a)
char a[sizeof &f];
                   ^

^ 在这里标记了声明符的结束和 f 作用域的开始。


我明白你的意思,但是声明符的语法非常明确。如果在任何声明列表之后声明符仍然可以在某种意义上“不完整”,我会期望标准这样说。即使在添加了-std=c89之后,gcc和clang仍然存在分歧,这是奇怪的。 - Seb Grindle
在C99中(具有标识符列表形式的函数仍然有效),完整声明符被定义为(6.7.5p2)“完整声明符是不是另一个声明符的一部分的声明符”。在这里,我认为我们承认void f(a) char a[sizeof &f];是一个完整的声明符。在DR#246中,当Clive使用“完整声明符的结尾”这个措辞来完成声明符时,C委员会似乎并没有反对。 - ouah
感谢提供DR#246的参考(指出其他人也认为“声明符已完成”这个短语很令人困惑)。委员会回应:“[...]当前措辞已足够清晰。”嗯。 - Seb Grindle

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