这是一个人为的例子,但表达了核心问题.我有一个union和一个结构,它具有来自现有代码库的相同嵌套结构:
typedef union _MyUnion
{
unsigned int A;
struct _MyNestedStruct
{
int field
} MyNestedStruct;
} MyUnion;
Run Code Online (Sandbox Code Playgroud)
和
typedef struct _MyStruct
{
struct _MyNestedStruct
{
int field
} MyNestedStruct;
} MyStruct;
Run Code Online (Sandbox Code Playgroud)
如果我在Green Hills Compiler(GHC)下编译,那么没有问题.在GCC下编译会给出错误"错误:重新定义'struct _MyStruct'".
首先,为什么我能够使用命名结构成功编译为嵌套结构?我怀疑GHC正在编译一些C++规则,或者它支持嵌套结构中的命名结构.
第二,什么才能让我成功编译而不需要任何重大的代码更改?我知道我可以从嵌套结构中删除_MyNestedStruct,但这会产生什么后果吗?
在C中,没有名称空间作用域,隐式或显式,因此所有结构名称共享相同的名称空间.因此,struct _MyNestedStruct定义了两次,这是一个错误.海湾合作委员会是正确的,GHC不是.
如果它是C++,那么代码是正确的,因为每个结构将创建一个不同的命名空间范围,因此没有名称冲突.
我能想到的解决方案:
A)如果结构实际上是相同的,只在其他结构之外定义一次(你可以将它放在第一个结构中,但那会很奇怪).
struct _MyNestedStruct
{
int field
};
typedef union _MyUnion
{
unsigned int A;
struct _MyNestedStruct MyNestedStruct;
} MyUnion;
typedef struct _MyStruct
{
struct _MyNestedStruct MyNestedStruct;
} MyStruct;
Run Code Online (Sandbox Code Playgroud)
B)将两种结构命名为不同的.在C中,名称并不那么重要,只要定义相同即可.
C)使用无名结构.我估计你根本就不会使用这些名字:
typedef union _MyUnion
{
unsigned int A;
struct
{
int field;
} MyNestedStruct;
} MyUnion;
typedef struct _MyStruct
{
struct
{
int field;
} MyNestedStruct;
} MyStruct;
Run Code Online (Sandbox Code Playgroud)
顺便说一句,请记住,任何以及下划线加上大写的名称都是为实现保留的,不应由用户定义.