C 变量定义与外部声明
C variable definition vs extern decleration
这似乎是那种已经涵盖的问题,但我似乎无法找出在哪里。
我遇到了 gcc 的一个特殊行为。
我文件A我有如下定义:
struct SomeStruct {
unsigned int uiVarA;
unsigned int uiVarB;
} SomeVar;
我文件 B 的外部声明不同:
extern struct SomeStruct {
unsigned char filler;
unsigned int uiVarA;
unsigned int uiVarB;
} SomeVar;
事实上,我可以将定义设为 double,将 extern decleration 设为 int,gcc 将在没有警告的情况下愉快地编译(甚至使用 -Wall 和 -Wextra)。
我只能得出结论,这一定意味着这是完全合法的行为,但怎么会这样呢?
我知道链接器负责映射两个变量,但是这个阶段没有错误检查吗?
除非您将一个文件包含在另一个文件中,否则编译器将看不到您的两个定义。
通常您只需在头文件中单独声明结构,然后声明该类型的变量,例如:
在a.h中:
struct SomeStruct {
unsigned int uiVarA;
unsigned int uiVarB;
}
在 a.c 中你可以做: struct SomeStruct SomeVar;
和在 b.c extern struct SomeStruct SomeVar
中包含 a.h 之后。或者更好的是,将外部结构放在头文件中,并将其包含在 a.c 和 b.c.
中
来自 C 规范
6.2.7 Compatible type and composite type
2 All declarations that refer to the same object or function shall have compatible type; otherwise, the behavior is undefined.
因此,它不是完全合法的行为,因为该行为未定义。但这并不意味着您的链接器有能力检查它。它在语法上是正确的(只要每个声明在不同的翻译单元中)。
这似乎是那种已经涵盖的问题,但我似乎无法找出在哪里。
我遇到了 gcc 的一个特殊行为。
我文件A我有如下定义:
struct SomeStruct {
unsigned int uiVarA;
unsigned int uiVarB;
} SomeVar;
我文件 B 的外部声明不同:
extern struct SomeStruct {
unsigned char filler;
unsigned int uiVarA;
unsigned int uiVarB;
} SomeVar;
事实上,我可以将定义设为 double,将 extern decleration 设为 int,gcc 将在没有警告的情况下愉快地编译(甚至使用 -Wall 和 -Wextra)。
我只能得出结论,这一定意味着这是完全合法的行为,但怎么会这样呢?
我知道链接器负责映射两个变量,但是这个阶段没有错误检查吗?
除非您将一个文件包含在另一个文件中,否则编译器将看不到您的两个定义。
通常您只需在头文件中单独声明结构,然后声明该类型的变量,例如:
在a.h中:
struct SomeStruct {
unsigned int uiVarA;
unsigned int uiVarB;
}
在 a.c 中你可以做: struct SomeStruct SomeVar;
和在 b.c extern struct SomeStruct SomeVar
中包含 a.h 之后。或者更好的是,将外部结构放在头文件中,并将其包含在 a.c 和 b.c.
来自 C 规范
6.2.7 Compatible type and composite type
2 All declarations that refer to the same object or function shall have compatible type; otherwise, the behavior is undefined.
因此,它不是完全合法的行为,因为该行为未定义。但这并不意味着您的链接器有能力检查它。它在语法上是正确的(只要每个声明在不同的翻译单元中)。