【问题标题】:Why can't I use the extern keyword for initializing an extern variable?为什么我不能使用 extern 关键字来初始化 extern 变量?
【发布时间】:2019-09-12 04:22:02
【问题描述】:

我在 stackoverflow 和其他网站上阅读了几个问题,在初始化全局变量时不能/不应使用 extern 关键字。但我想了解,为什么这是不可能的。

C 标准的哪些条款导致这是不可能的?我认为它隐藏在“6.7 声明”或“6.9 外部定义”部分中。我想我找不到合适的段落,因为我对其他部分的一些限制缺乏了解。

让我感到困惑的是“6.9.2 外部对象定义”部分的示例 1。在这里我在第 3 行找到

extern int i3 = 3;  // definition, external linkage

这是使用extern 关键字初始化全局变量。但是示例或相关部分中没有任何词表明这不是“严格符合程序”。

代码示例:

extern int var = 5;

int main(void)
{
        return var;
}

使用gcc -Wall -Wextra --pedantic -std=c11 file.c 编译此代码时,我收到以下警告(gcc 8.3.0):

file.c:1:12: warning: 'var' initialized and declared 'extern'
 extern int var = 5;
            ^~~

【问题讨论】:

标签: c language-lawyer c11


【解决方案1】:

extern 关键字可以用就好了,只是用处不大。

你的例子

extern int var = 5;

在全局范围内等价于

int var = 5;  // variable definition

全局变量默认有外部链接。这两行都定义了同一个变量。

但是,如果您要声明一个外部变量(即“这个东西存在但在别处定义”),您需要使用extern 而不使用初始化器:

extern int var;  // just a declaration; var is defined elsewhere

这类似于定义一次的函数:

// definition
int foo(void) {
    ...
}

并在需要的地方声明,通常在标题中:

int foo(void);  // declaration; foo is defined elsewhere

从技术上讲,您还可以将 extern 关键字与函数一起使用:

// definition
extern int foo(void) {
    ...
}

extern int foo(void);  // declaration

这只是多余的。

extern 唯一不冗余的地方是在声明(但不定义)全局变量时,然后你不能有初始化程序(这是定义的一部分)。

为了完整起见,您可以在局部范围内声明一个全局变量:

int main(void) {
    extern int var;
}

但是,在此处添加初始化程序会使其成为硬错误:

int main(void) {
    extern int var = 42;
}
try.c:2:16: error: 'var' has both 'extern' and initializer

这是因为你只能在局部范围内声明(但不能定义)全局变量。

在您的情况下,编译器会发出警告

file.c:1:12: warning: 'var' initialized and declared 'extern'

因为extern 的存在通常意味着程序员打算编写一个变量声明(为什么要使用extern?),但初始化程序将其改为定义。

【讨论】:

  • 使用extern 关键字的一点是要明确链接。
  • 该问题被标记为 language-lawyer 并明确询问 C 标准的条款,但此答案根本没有引用该标准。
  • @EricPostpischil 是的,但问题是“C 标准的哪些条款导致这是不可能的?”。答案是“没有”,因为这是可能的。我应该在这里引用什么?
  • @melpomene:说这是可能的部分。
猜你喜欢
  • 2016-10-08
  • 1970-01-01
  • 2011-02-14
  • 2012-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-03
相关资源
最近更新 更多