2017-08-15 44 views
1

下面的代碼在Keil下使用ARMCC編譯C語言,但無法使用C++編譯,在eclipse下使用G ++。原來的代碼有一些const關鍵字,但似乎導致另一個不太重要的問題,所以我現在刪除它們。循環依賴結構,使用前向聲明時對struct的錯誤重定義

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, 
}; 

至於我可以告訴大家,第一行是一個聲明,而不是定義,因此,「重新定義錯誤」不應該發生......

+2

C和C++是兩種不同的語言,例如,你不需要'用C的typedef struct' ++。 –

+1

除了宏名稱和枚舉常量外,請不要使用全大寫。它很混亂,很難閱讀。 –

回答

4

隨着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, 
}; 

... 
+0

是的。這絕對是正確的答案。 –