C变量定义vs extern decleration

时间:2015-09-21 12:42:51

标签: c gcc extern

这似乎已经涵盖了那类问题,但我似乎无法找到答案。

我遇到过gcc的特殊行为。

我提交A我有以下定义:

NSDictionary *nameDict = self.jsonArray[0];
NSLog(@"Name = %@", nameDict[@"name"]); // This prints Name = XYZ

我提交B extern decleration不同:

struct SomeStruct {
  unsigned int uiVarA;
  unsigned int uiVarB;
} SomeVar;

实际上我可以将定义设为double,extern decleration是一个int,gcc很乐意编译而不需要警告(使用-Wall和-Wextra)。

我只能得出结论,这必然意味着它是完全合法的行为但是如此呢?

我知道链接器完成映射两个变量的工作但是在这个阶段没有错误检查吗?

2 个答案:

答案 0 :(得分:4)

除非您在另一个文件中包含一个文件,否则编译器将不会看到您的两个定义。

通常,您只需单独在头文件中声明结构,然后声明该类型的变量,如:

在a.h中:

struct SomeStruct {
   unsigned int uiVarA;
   unsigned int uiVarB;
}       

在a.c中,您可以在包含a.h后执行:struct SomeStruct SomeVar;和b.c extern struct SomeStruct SomeVar。或者更好的是,将extern结构放在头文件中,并在a.c和b.c中包含它。

答案 1 :(得分:3)

来自C Spec。

  

6.2.7兼容类型和复合类型

     
    

2所有引用同一对象或函数的声明都应具有兼容的类型;否则,行为是未定的。

  

因此,行为未定义并非完全合法的行为。但这并不意味着您的链接器能够检查它。它在语法上是正确的(只要每个声明都在不同的翻译单元中)。