【问题标题】:In C89, what is the scope of a function name in an 'old-style' function definition?在 C89 中,“旧式”函数定义中函数名的范围是什么?
【发布时间】:2014-11-07 17:37:48
【问题描述】:

以下 C89 是否合法?

void f(a)
char a[sizeof &f];
{
}

我的想法是肯定的,因为在任何块范围之外声明的标识符的范围在声明符结束后立即开始并延伸到翻译单元的末尾。因此,“f”的范围包括声明列表。

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

【问题讨论】:

    标签: c gcc clang standards-compliance c89


    【解决方案1】:

    来自 C90 标准(重点是我的)

    (C90, 6.1.2.1) “结构、联合和枚举标记的范围在标记出现在声明标记的类型说明符之后开始。每个枚举常量的范围都在出现之后开始它在枚举器列表中定义枚举器。任何其他标识符的范围都在其声明器完成后开始。"

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

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

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

    ^ 此处标记了声明符的完整位置以及 f 范围的开始位置。

    【讨论】:

    • 我明白你的意思,但声明符的语法非常明确。如果在任何声明列表之后,声明符在某种意义上仍然是“不完整的”,我希望标准会这样说。 gcc 和 clang 不同意的事实(即使在添加 -std=c89 之后)很奇怪。
    • @SebGrindle 在 C99 中(具有标识符列表形式的函数在 c99 中仍然有效),完整的声明符定义为 (6.7.5p2) a "完整的声明符是一个声明符,它是不是另一个声明符的一部分” 我认为我们承认void f(a) char a[sizeof &f]; 是一个完整的声明符。在 DR#246 中,当 Clive 使用 end of the full declarator 来完成声明符时,C 委员会似乎并没有反对错误。
    • 感谢对 DR#246 的引用(指出其他人也认为“声明符已完成”这句话令人困惑)。委员会回应说“[..] 目前的措辞已经足够清楚了”。嗯。
    猜你喜欢
    • 2017-07-13
    • 1970-01-01
    • 2021-08-29
    • 1970-01-01
    • 2017-08-07
    • 2015-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多