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

C 块内变量的声明也是定义吗?,c,language-lawyer,declaration,definition,c11,C,Language Lawyer,Declaration,Definition,C11,C11标准在第6.7/5节中规定了哪些声明也是定义: C116.7/5 标识符的定义是该标识符的声明 即: -对于对象,导致为该对象保留存储 (……) 那么,块内变量的声明也是定义吗?例如: void Bla(void) { int a; // Is this declaration also a definition? } 我在stackoverflow上找到了以下两个答案,即块内变量的声明也是定义: 然而,“Michael Burr”提供的答案引用了6.2.2/2“标识符的

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

C116.7/5

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

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

(……)

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

void Bla(void) {
    int a; // Is this declaration also a definition?
}
我在stackoverflow上找到了以下两个答案,即块内变量的声明也是定义:

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

请提供C标准的参考。

美国第6.2.2p6节:

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

缺少的部分是第6.2.2p6节:

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

在没有存储类说明符(即
静态
外部
)的块内声明的变量具有无链接,且无链接变量的每个声明都是唯一的对象。因为声明是唯一的,所以它也可以作为一个定义

另见第6.7p7节:

如果对象的标识符声明时没有链接, 该对象的类型应在其使用期限结束时完成 声明程序,或在其init声明程序的末尾(如果有) 初始值设定项;对于功能参数(包括 原型),这是需要调整的类型(见6.7.6.3) 完成

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

以下是如何从标准中看出这一点(所有参考文献均参考,这是最接近于免费公开的C2011官方文本):

首先,他说

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

第二,他说

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

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

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

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

(使用
extern
在block scope中声明一个对象会给它带来外部链接,而不是一个定义。如果你在阅读了我引用的所有章节后不明白为什么会这样,请特别提出一个新问题。)