【问题标题】:Is a declaration of a variable inside a block also a definition?块内的变量声明也是定义吗?
【发布时间】:2018-08-19 18:23:22
【问题描述】:

C11 标准在第 6.7/5 节中指定了哪些声明也是定义:

C11 6.7/5

标识符的定义是对该标识符的声明 那:

——对于一个对象,导致为该对象保留存储空间;

(...)

那么块内的变量声明也是定义吗?例如:

void Bla(void) {
    int a; // Is this declaration also a definition?
}

我在stackoverflow上找到了以下两个答案,其中声明块内的变量声明也是定义:

但是,“Michael Burr”提供的答案是指 6.2.2/2 “标识符的链接”,以解释块范围内的变量声明也是定义。对我来说,他的参考并没有回答我的问题。第二个链接中的答案没有提供对 C 标准的任何参考。 C 标准中是否还有其他段落可以作为参考来确认这些答案?

请提供对 C 标准的参考。

【问题讨论】:

    标签: c language-lawyer declaration definition c11


    【解决方案1】:

    是的,在块范围内声明“对象”(C 标准避免使用“变量”一词)是一个定义,除非该对象的声明使用存储类说明符 extern,其中如果它不是一个定义。

    从标准中可以看出这一点(所有引用均指向N1570,这是与免费公开的 C2011 官方文本最接近的近似值):

    首先,6.2.2p6

    以下标识符没有链接: ... 一个没有存储类说明符 extern 声明的对象的块范围标识符。

    第二,6.7p5

    标识符的定义是对该标识符的声明: * 对于一个对象,导致为该对象保留存储空间;

    最后是6.2.4,您需要完整阅读它,但最重要的部分在第 5 和第 6 段:

    一个对象,其标识符被声明为没有链接并且没有存储类说明符 static 具有自动存储持续时间......它的生命周期从进入与其关联的块开始,直到该块的执行以任何方式结束。

    因此,如果您在块范围内声明一个没有extern 的对象,它就没有链接。没有链接的对象具有自动存储持续时间,除非它使用static 声明,在这种情况下它具有静态存储持续时间,请参阅 6.2.4 中我没有引用的部分。具有自动存储持续时间的对象在进入声明它的块时为其保留存储空间,具有静态存储持续时间的对象在程序启动时为其保留存储空间(再次,请参阅 6.2.4 的部分我没有引用)。因此,任何不提供链接的对象声明都是定义。

    (在块范围内声明对象 with extern 给它外部链接,不是定义。如果你不明白为什么会这样阅读我引用的所有部分以及6.9,请专门提出一个新问题。)

    【讨论】:

      【解决方案2】:

      C standard 的第 6.2.2p6 节指出:

      在一组翻译单元和库中 构成一个完整的程序,一个特定的每个声明 带有外部链接的标识符表示相同的对象或 功能。在一个翻译单元内,每个声明 具有内部链接的标识符表示相同的对象或 功能。 每个没有链接的标识符声明 表示一个独特的实体。

      缺少的部分是第 6.2.2p6 节:

      以下标识符没有链接:声明为的标识符 不是对象或函数;标识符 声明为函数参数; 块范围标识符 对于没有存储类说明符 extern 声明的对象。

      在没有存储类说明符的块内声明的变量(即staticextern)具有无链接,并且没有链接的变量的每个声明都是独特的对象。因为声明是唯一的,所以它也有资格作为定义。

      另见第 6.7p7 节:

      如果一个对象的标识符被声明为没有链接, 对象的类型应在其结束时完成 声明符,或者在它的 init-declarator 末尾,如果它有 初始化器;在函数参数的情况下(包括在 原型),它是调整后的类型(见 6.7.6.3),需要 完成。

      【讨论】:

        猜你喜欢
        • 2021-12-14
        • 1970-01-01
        • 2016-09-07
        • 1970-01-01
        • 2011-04-30
        • 1970-01-01
        • 2015-01-26
        • 2014-04-16
        • 1970-01-01
        相关资源
        最近更新 更多