其中用C原因存储对象声明要预约(即是定义)?
C11指定6.7节,其声明也定义:其中用C原因存储对象声明要预约(即是定义)?
的标识符的定义是该标识符的声明:
- 为一个对象,使存储到该对象保留;
[...]
我没有找到一个全面的列表,它的对象声明导致存储被保留。直觉上我很清楚,但我无法从C11标准中获取这些信息。
没有确定的列表,因为标准只是描述了什么是定义并且它不在一个地方。我会尽量在这里总结一下。我只用型int
这里没有一致性任何限定词(如const
)。
-
如果添加初始化器的声明,它总是一个定义:
int x = 1;
-
如果没有初始化,以下是定义当他们在功能范围 :
int x; auto int x; // auto is the default anyways register int x; // register is just a hint, but would be "storage" as well static int x; // also reserves storage, but with static duration
-
在文件范围,规则是一个比较复杂;以下是暂定定义:
int x; static int x;
标准(§6.9.2p2)的措辞:
的标识符的对象具有文件作用域没有初始化的声明,和 没有存储类说明或与存储类说明
static
,构成了 暂定定义。如果翻译单元包含一个 标识符的一个或多个试探性的定义,和翻译单元包含该标识符的外部定义,然后 行为是完全一样,如果翻译单元包含 标识符的文件范围内声明,与至0复合类型作为翻译单元的端部,具有一个初始化 等于所以这意味着他们最终“成为定义”,如果他们没有找到参考另一个定义。
-
随着存储类
extern
并没有初始化,你没有一个定义:extern int x; // <- not a definition
AFAIK,这应该是完整的一套规则。如果我忘记了某些东西,请随时编辑/评论。
还有'_Thread_local'声明的情况,它似乎遵循与试探性定义类似的规则,只是标准只在6.7.9中这么说。可能他们不想将它列为临时定义,因为这样的'_Thread_local'声明有效地为每个线程声明了一个对象。 –
很明显,它们不是对象,但也许值得注意的是,在内联函数实例的上下文中,有些令人困惑的重载使用“extern”。坦率地说,我不太明白为什么简单的'inline'和'extern inline'的语义没有颠倒过来。 – doynax
咦?当我阅读它时,*声明*不会导致任何内容被保留。 –
任何不使用'extern'存储类的。 –
@EugeneSh。每个定义同时是一个声明,反之亦然。 –