在C中遗漏变量extern,但仍然有效?

时间:2016-03-21 21:23:31

标签: c global-variables extern

我很困惑,为什么以下工作:

test.c的

#include <stdio.h>

int g;
// ??? should be extern int g; ??? 

int main(){
  printf("%i\n", g);
  return 0;
}

lib.c

int g = 3;

编译时为什么没有出现重复的符号错误?我尝试在C ++中执行此操作时收到错误,以便让我满意。然而,在这个例子中,无论我是否包括extern,一切都编译和工作(即成功打印3)。从阅读有关C中extern的StackOverflow上的所有其他问题,每个人似乎都在说变量上使用的extern声明变量但不为它定义(即分配内存)。但是在这里,如果我不使用extern,那么我定义了两个单独的变量,都称为g,因此应该存在某种重复的符号错误。但是没有,所以我很困惑。

1 个答案:

答案 0 :(得分:1)

N1570,6.9.2(强调我的):

  

2具有文件范围的对象的标识符声明   没有初始化程序,没有存储类说明符或者没有   存储类说明符静态,构成一个暂定的   定义

     

4例1

      int i1 = 1;                    // definition, external linkage
      static int i2 = 2;             // definition, internal linkage
      extern int i3 = 3;             // definition, external linkage
      int i4;                        // tentative definition, external linkage
      static int i5;                 // tentative definition, internal linkage
      int   i1;                      // valid tentative definition, refers to previous
      int   i2;                      // 6.2.2 renders undefined, linkage disagreement
      int   i3;                      // valid tentative definition, refers to previous
      int   i4;                      // valid tentative definition, refers to previous
      int   i5;                      // 6.2.2 renders undefined, linkage disagreement
      extern    int   i1;            // refers to previous, whose linkage is external
      extern    int   i2;            // refers to previous, whose linkage is internal
      extern    int   i3;            // refers to previous, whose linkage is external
      extern    int   i4;            // refers to previous, whose linkage is external
      extern    int   i5;            // refers to previous, whose linkage is internal

“test.c”中的int g;是一个暂定的定义,给出g外部链接(参见示例)。但是,“lib.c”中的int g = 3;有一个初始化,因此它不是一个暂定的定义。因此,“test.c”中的g引用“lib.c”中的g,其值初始化为3.

另请参阅:http://en.cppreference.com/w/c/language/extern