【问题标题】:duplicate declaration global variable in C [duplicate]C中的重复声明全局变量[重复]
【发布时间】:2018-01-15 18:56:32
【问题描述】:

为什么这在全球范围内有效:

static int a;
static int a=0;

但不在函数体内:

void foo()
{
    static int b;
    static int b=0; //error: Duplicate declaration of global variable 'b'
    ...

使用 clion 2017.3.1、C99、gcc5.4

【问题讨论】:

  • @EugeneSh.,。我不认为这是引用问题的重复。引用的候选重复问题没有解决函数内声明/定义的静态变量与函数外声明/定义的静态变量之间的不一致。
  • 我认为问题本身正在解决它:暂定定义是没有存储类说明符和初始化程序的任何外部数据声明
  • @EugeneSh。是的,我明白你的意思。我认为它部分回答了这个问题,或者至少对于 OP 的场景来说不够明确。
  • @EugeneSh。这个措辞很不幸,因为带有存储类说明符 static 的文件范围声明也构成了一个暂定定义。最好使用 C 中的定义:“具有文件范围的对象的标识符声明没有初始化程序,并且没有存储类说明符或存储类说明符静态,构成一个暂定定义。”

标签: c variables duplicates global declaration


【解决方案1】:

第一个,在全局范围内,是所谓的Tentative definition 的示例。

暂定定义是一个没有初始化器的外部声明,或者没有存储类说明符或带有说明符 static。

暂定定义是一个声明,可能会或可能不会作为定义。如果在同一个翻译单元中更早或更晚地找到了实际的外部定义,则暂定定义仅充当声明。

在第二个示例中,b 具有块作用域并且没有链接,换句话说:声明不是外部的。因此,暂定定义规则不适用。

【讨论】:

  • 在第二个示例中,您处于函数范围内。 这是块范围而不是函数范围。块作用域和函数作用域是四种作用域中的两种。
  • @ouah 好的,谢谢。
  • "如果在同一个翻译单元中更早或更晚地发现了一个实际的外部定义,那么这个暂定定义就只是一个声明。"是否存在重复外部定义的合理方案?
【解决方案2】:

在第一个代码 sn-p 中,您有 C 所谓的 暂定定义 和外部定义:

(C11, 6.9.2p2) “具有文件范围的对象的标识符声明没有初始值设定项,并且没有存储类说明符或存储类说明符静态,构成暂定定义。[... ]"

在第二个代码 sn-p 中,您不在文件范围内,而是在块范围内,这就是不允许的原因。

【讨论】:

  • @coderredoc 只有文件作用域代码 sn -p 中的第一个声明构成了暂定定义。由于紧随其后的是外部定义,因此此处将暂定定义视为引用声明。
  • 有什么规则说外部定义和临时定义可以共存? 6.9.2 没有。这就是为什么我什至不说他们就从不同的角度接近了答案。
  • @coderredoc 我的理解是没有禁止它的规则。暂定定义仅在没有外部定义的情况下才成为对象的定义(根据 6.9.2p2),因此它不是此处的定义,因为它不为该对象保留存储空间。但它用作标识符的声明(仍然按照 6.9.2p2),并且正如您从 6.7p3 中引用的那样,仅当标识符没有链接时,才明确禁止在同一范围内使用兼容类型的标识符的多个声明。
  • @coderredoc 请注意,6.9.2p4 的(非规范)示例显示了外部定义和暂定定义(i1 标识符)。
  • 第一个评论是按照规则。尽管第二个示例并没有破坏相同的内容(通过示例)。这就是为什么我直接说适用于此处的有关声明的标准部分。但是是的,第二个是 ext def (file sope and an initializer),第一个是 tent def。 (令人惊讶的是,这一切也可以用不同的方式解释)。
猜你喜欢
  • 2014-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多