循环依赖结构,使用前向声明时重新定义结构错误

Posted

技术标签:

【中文标题】循环依赖结构,使用前向声明时重新定义结构错误【英文标题】:Circular dependency struct, error redefinition of struct when using forward declaration 【发布时间】:2017-08-15 19:58:22 【问题描述】:

下面的代码在C中编译,在Keil下使用ARMCC,但是在C++中编译失败,在eclipse下使用G++。原始代码有一些 const 关键字,但这似乎导致了另一个不太重要的问题,所以我暂时删除了它们。

struct MENU

    struct MENU *   NextMenu;
    struct MENU *   PrevMenu;
    void            (* InitFunction)(void);
;

typedef struct MENU MENU_T;

MENU_T MENU_A; // <- this forward declaration is needed for circular reference between structs
MENU_T MENU_B;
MENU_T MENU_C;

MENU_T
MENU_A = // <- However redefinition error occurs here

    .NextMenu = &MENU_B,
    .PrevMenu = &MENU_C,
    .InitFunction = 0,
;

MENU_T
MENU_B =

    .NextMenu = &MENU_C,
    .PrevMenu = &MENU_A,
    .InitFunction = 0,
;

MENU_T
MENU_C =

    .NextMenu = &MENU_A,
    .PrevMenu = &MENU_B,
    .InitFunction = 0,
;

据我所知,第一行是声明而不是定义,所以“错误重新定义”不应该发生......

【问题讨论】:

C 和 C++ 是两种不同的语言,例如 C++ 中不需要typedef struct 请不要对除宏名称和枚举常量以外的任何内容使用全大写。它令人困惑且难以阅读。 【参考方案1】:

使用MENU_T MENU_A;,您无需“前向声明”名为MENU_A 的变量,而是定义它。因此,当您稍后编写MENU_T MENU_A = ... 时,您会收到一个错误,表明您重新定义了一个具有相同名称的变量MENU_A

如果只是声明一个变量(不定义它),请使用关键字extern

extern MENU_T MENU_A; // declaration of MENU_A, not a definition
extern MENU_T MENU_B;
extern MENU_T MENU_C;

MENU_T MENU_A = 

    .NextMenu = &MENU_B,
    .PrevMenu = &MENU_C,
    .InitFunction = 0,
;

...

【讨论】:

以上是关于循环依赖结构,使用前向声明时重新定义结构错误的主要内容,如果未能解决你的问题,请参考以下文章

带有前向声明的循环包含和继承导致 C2504 基类未定义

头文件之间的循环依赖

C++ 简单循环引用和前向声明问题

C++ 类的前向声明的用法

20210421-C++的前向声明

将结构前向声明为类时出现 Visual C++ 2015 链接器错误