重用的命名结构作为嵌套结构会触发GCC中的重定义错误

Jos*_*hua 2 c struct unions

这是一个人为的例子,但表达了核心问题.我有一个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,但这会产生什么后果吗?

rod*_*igo 8

在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)

顺便说一句,请记住,任何以及下划线加上大写的名称都是为实现保留的,不应由用户定义.