块内的变量声明也是一个定义吗?

Sin*_*kus 4 c declaration definition language-lawyer c11

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

C11 6.7/5

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

- 对于一个对象,导致为该对象保留存储;

(......)

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

void Bla(void) {
    int a; // Is this declaration also a definition?
}
Run Code Online (Sandbox Code Playgroud)

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

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

请提供C标准的参考.

zwo*_*wol 7

是的,在块作用域中声明"对象"(C标准避免使用"变量"一词)是一个定义,除非该对象的声明使用存储类说明符extern,在这种情况下它不是定义.

以下是从标准中看到的内容(所有参考文献均为N1570,这是与C2011官方文本最接近的免费公开版):

首先,6.2.2p6

以下标识符没有链接:...没有存储类说明符extern声明的对象的块作用域标识符.

第二,6.7p5

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

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

标识符未声明链接且没有存储类说明符静态的对象具有自动存储持续时间...其生命周期从条目扩展到与其关联的块,直到该块的执行以任何方式结束.

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

(于方块作用域的对象的申报 extern给它外部链接,是不是一个定义.如果你不明白为什么那就是通过所有章节看完后我报价,还6.9,请明确提出新问题有关.)