在C89中,';旧式';函数定义?

在C89中,';旧式';函数定义?,c,gcc,clang,standards-compliance,c89,C,Gcc,Clang,Standards Compliance,C89,以下是合法的C89吗 void f(a) char a[sizeof &f]; { } 我的想法是肯定的,因为在任何块范围之外声明的标识符的范围在声明器结束后立即开始,并扩展到翻译单元的结束。因此,“f”的范围包括声明列表 “gcc-学究-墙”接受了它。 “叮当-学究-墙”拒绝了它,就像C90标准中的lcc一样。(强调我的) (C90,6.1.2.1)结构、联合和枚举标记的作用域在声明标记的类型说明符中标记出现后立即开始。每个枚举常量的作用域都在其定义枚举数出现在枚举数列表中后立即开始

以下是合法的C89吗

void f(a)
char a[sizeof &f];
{
}
我的想法是肯定的,因为在任何块范围之外声明的标识符的范围在声明器结束后立即开始,并扩展到翻译单元的结束。因此,“f”的范围包括声明列表

“gcc-学究-墙”接受了它。 “叮当-学究-墙”拒绝了它,就像C90标准中的lcc一样。

(强调我的)

(C90,6.1.2.1)结构、联合和枚举标记的作用域在声明标记的类型说明符中标记出现后立即开始。每个枚举常量的作用域都在其定义枚举数出现在枚举数列表中后立即开始任何其他标识符的作用域都是在其声明符完成后立即开始的。

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

编辑:魔鬼在细节中(单词completion),经过再三考虑,我认为这不是一个有效的函数声明,因为声明符在
void f(a)
之后不完整


^
这里标记了声明符的完成位置和范围的开始位置。

我明白你的意思,但是声明符的语法非常明确。如果声明符在任何声明列表之后在某种意义上仍然是“不完整的”,我希望标准会这样说。gcc和clang不同意这一事实(即使在添加了-std=c89之后)也很奇怪。@C99中的SebGrindle(具有标识符列表形式的函数在C99中仍然有效),完整声明器被定义为(6.7.5p2)“完整声明器是一个声明器,它不是另一个声明器的一部分”,在这里我想我们承认
void f(a)char a[sizeof&f];
是一个完整的声明人。在C语言中,当克莱夫用完整声明人的结尾来完成声明人时,委员会似乎并不反对错误。感谢你提到DR#246(指出其他人也认为“声明人已完成”一词令人困惑)。委员会回答“[…]目前的措辞已经足够清楚了”。
void f(a)
char a[sizeof &f];
                   ^