【问题标题】:Why is the storage class of global variables in C implicitly defined as "extern"?为什么C中全局变量的存储类隐式定义为“extern”?
【发布时间】:2017-07-10 17:19:00
【问题描述】:

当我们声明任何全局变量时,例如

int x;

相当于

extern int x; 

现在默认情况下,编译器将全局变量初始化为 0,这意味着它们被分配了内存。但是如果我简单地写

extern int x;

那么这只会声明变量,而不会为其分配内存。所以,我的疑问是,如果我在int x 之前写extern 或者我不写,如果是全局变量,编译器会如何区别对待它们?在我写int x的情况下,它分配内存,同时它把extern放在int x之前,而在我写extern int x的情况下,它只声明变量而没有内存分配给它。请说明编译器在这两种情况下的行为方式。

【问题讨论】:

  • int x; 不等于 extern int x;(您似乎在最后一段中承认了这一点)
  • 问题是为什么你认为一个全局变量被声明为extern

标签: c scope global-variables extern


【解决方案1】:

您问题的前提是不正确的。这个

int x;

是一个暂定的定义(在翻译单元结束时会变成x的正常定义)。

这个

extern int x; 

是一个非定义的声明,根本就不是定义。

它们甚至不完全等价。

您的原始定义的松散等效项是

extern int x = 0;

这是一个定义。但这不是完全等价的,因为这个定义不是试验性的。

关键字extern 当(且仅当)没有显式初始化器时将对象定义转换为非定义声明。如果存在显式初始化程序,则定义仍然是定义,即使您将 extern 添加到它。

【讨论】:

    【解决方案2】:

    这可以通过了解外部对象定义和Tentative definition来回答。

    引用C11,第 §6.9.2 章,(强调我的

    声明一个对象的标识符,该对象具有文件范围而没有初始化程序,以及 没有存储类说明符或带有存储类说明符 static,构成一个 暂定定义。如果一个翻译单元包含一个或多个暂定定义 标识符,并且翻译单元不包含该标识符的外部定义,则 该行为就像翻译单元包含该文件的文件范围声明一样 标识符,具有从翻译单元末尾开始的复合类型,带有初始化器 等于 0。

    【讨论】:

    • 我想知道为什么人们仍然忽略标准应该至少阅读一次这一事实。
    • @Michi 同意。很多时候,标准文本似乎有点棘手,但经过仔细研究,这是一个可以真正回答大多数问题的权威来源。
    猜你喜欢
    • 2015-06-23
    • 1970-01-01
    • 2011-04-28
    • 2019-07-23
    • 1970-01-01
    • 2015-08-08
    • 2011-04-04
    • 1970-01-01
    相关资源
    最近更新 更多