C 中的哪些对象声明会导致保留存储(即定义)?



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

标识符

的定义是该标识符的声明,它:
— 对于对象,导致为该对象保留存储;
[...]

我没有找到哪些对象声明导致存储被保留的完整列表。 直觉上我很清楚,但我无法从 C11 标准中获取这些信息。

没有明确的列表,因为标准只是描述了什么是定义,而不是在一个地方。我将尝试在这里总结一下。为了保持一致性,我将在这里只使用没有任何限定符(如const(的类型int

  • 如果将初始值设定项添加到声明,则它始终是一个定义

    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,这应该是完整的规则集。如果我忘记了什么,请随时编辑/评论。

最新更新