【问题标题】:A reused named struct as a nested struct triggers a redefinition error in GCC重用命名结构作为嵌套结构会触发 GCC 中的重新定义错误
【发布时间】:2012-11-05 23:58:30
【问题描述】:

这是一个人为的例子,但表达了核心问题。我在现有代码库中有一个联合和一个具有相同嵌套结构的结构:

typedef union _MyUnion
{
  unsigned int A;
  struct _MyNestedStruct
  {
    int field
  } MyNestedStruct;
} MyUnion;

typedef struct _MyStruct
{
  struct _MyNestedStruct
  {
    int field
  } MyNestedStruct;
} MyStruct;

如果我在 Green Hills Compiler (GHC) 下编译,则没有问题。在 GCC 下编译会报错“error: redefinition of 'struct _MyStruct'”。

首先,为什么我能够将命名结构作为嵌套结构成功编译?我怀疑 GHC 正在使用一些 C++ 规则进行编译,或者它支持嵌套结构中的命名结构。

其次,什么可以让我在不进行任何重大代码更改的情况下成功编译?我知道我可以从嵌套结构中删除 _MyNestedStruct,但这有什么后果吗?

【问题讨论】:

  • 也许你真的在重新定义结构,因为我可以在这里的许多 GCC 发行版中很好地编译它。
  • 是否有任何理由将 MyNestedStruct 更改为声明而不是定义?也就是说,在包含 union/struct 的外部定义 _MyNestedStruct,然后在容器内声明该结构的实例
  • @FlávioToribio:也许你正在将它编译为 C++,因为我得到了错误。
  • 我刚刚注意到他使用了相同的结构名称,并且可能将两个 typedef 放在同一个源中。

标签: c struct unions


【解决方案1】:

在 C 中没有隐式或显式的命名空间范围,因此所有结构名称共享相同的命名空间。因此,struct _MyNestedStruct 被定义了两次,这是一个错误。 GCC 是正确的,GHC 不是。

如果是 C++,那么代码是正确的,因为每个结构都会创建不同的命名空间范围,因此不会发生名称冲突。

我能想到的解决方案:

A) 如果结构实际上是相同的,则只在其他结构之外定义一次(您可以将它放在第一个结构中,但这会很奇怪)。

struct _MyNestedStruct
{
    int field
};

typedef union _MyUnion
{
  unsigned int A;
  struct _MyNestedStruct MyNestedStruct;
} MyUnion;

typedef struct _MyStruct
{
  struct _MyNestedStruct MyNestedStruct;
} MyStruct;

B) 以不同的方式命名这两个结构。在 C 中,名称并不那么重要,只要定义相同即可。

C) 使用无名结构。我认为您根本不会使用这些名称:

typedef union _MyUnion
{
  unsigned int A;
  struct
  {
    int field;
  } MyNestedStruct;
} MyUnion;

typedef struct _MyStruct
{
  struct
  {
    int field;
  } MyNestedStruct;
} MyStruct;

顺便说一句,请记住,任何以和下划线加大写字母开头的名称都是为实现保留的,不应由用户定义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-17
    • 2019-05-27
    • 1970-01-01
    • 2016-05-03
    • 1970-01-01
    • 2018-12-22
    • 1970-01-01
    相关资源
    最近更新 更多