今天遇到了一个很愚蠢的错误,记录下来。
问题
extern Reg_Flag reg_flag;
extern Reg_Value reg_value;
typedef struct {
uint8_t DO1;
uint8_t DO2;
uint8_t DO3;
uint8_t DO4;
uint8_t AO1;
uint8_t AO2;
uint8_t AO3;
uint8_t AO4;
uint8_t DI1;
uint8_t DI2;
uint8_t DI3;
} Reg_Flag;
编译时,出现error: identifier “Reg_Flag” is undefined
extern Reg_Flag reg_flag;
但很奇怪,我明明已经定义了。无非就是定义是在extern的下面,会不会是这个原因?
解决
果然,把extern的部分放到结构体定义的下面之后,编译成功了。那这是为什么呢?
typedef struct {
uint8_t DO1;
uint8_t DO2;
uint8_t DO3;
uint8_t DO4;
uint8_t AO1;
uint8_t AO2;
uint8_t AO3;
uint8_t AO4;
uint8_t DI1;
uint8_t DI2;
uint8_t DI3;
} Reg_Flag;
extern Reg_Flag reg_flag;
其实很简单,
在C语言中,编译是从上到下进行的。当编译器遇到extern声明时,它需要知道这个变量的类型。如果类型还没有定义,编译器就不知道如何处理这个声明,因此会报错。
比如编译器在遇到extern Reg_Flag reg_flag;时,还不知道Reg_Flag是什么类型,因为它在代码中还没有定义。所以编译器会报错identifier “Reg_Flag” is undefined。
通过先定义类型,再进行extern声明,可以确保编译器在处理extern声明时已经知道了这些类型,确保编译成功!
补充
'extern’关键字:用于声明一个变量或函数是在别处定义的,意味着它告诉编译器期望在其他地方找到这个变量或函数的定义。
【注】
(1)首先要确保使用’extern’关键字引用的变量的类型都已经被定义。
(2)类型定义后,再用’extern’声明这些外部变量,这样编译器能够理解这些变量的完整类型信息。