2013-08-30 17 views
1

我有一個預處理器宏,它根據宏參數生成函數和變量。預處理器:使用動態名稱生成函數。多重定義問題

調用帶有宏觀sequently,B由於宏頭文件中定義的宏將產生類似

Inst* AActivate() { ... } 
bool Atemp; 

Inst* BActivate() { ... } 
bool Btemp; 

,我得到的鏈接錯誤通知我關於已定義的符號。 我使用#pragma一次,但我想問題在於實現標題內的功能。

這裏的宏:

#define REGISTER(ns, id, type) \ 
     Inst* type##Activate() { return new type(); }\ 
     bool type##temp = RegisterType(ns << 8 | id, &type##Activate); 

現在我不知道如何處理這樣的問題。 我的第一個想法是使用一些#defense-Guards,但顯然這需要嵌套的#defines,這在C++中是不可能的。 我讀了關於一個可能的解決方案,但很不幸,我無法使用這些庫。

有什麼想法?

預先感謝您...

回答

3

你的宏產生了頭功能定義,像任何正常功能,如果頭被包含在一個以上的翻譯頭非內聯函數違反ODR單元。所以只需使內聯的生成函數。

對於ODR也適用的全局變量,您必須將它們聲明爲static或const才能獲得內部鏈接。這反過來會給你多個獨立的變量實例,每個翻譯單元的頭部被包括在內。無論如何,全局變量被認爲是不好的風格,所以也許你應該考慮其他的東西。

+0

謝謝你,我已經嘗試中的#define宏中定義的*激活,內聯函數,但令人驚訝的多重定義錯誤仍然出現......這是連接到我 – mbue

+0

啊,沒關係,愚蠢的我...我在VS編譯錯誤的項目文件。使用內聯它當然是有效的。謝謝 – mbue

0

在.cpp文件中使用宏或內聯函數。它並沒有真正幫助你使用#pragma一次,因爲它只停止每個.cpp文件包含頭一次以上。當你編譯幾個.cpp文件時,函數會被定義好幾次。

0

你爲C和C++都標記了,你真的應該決定使用哪一個。

像這樣的事情只能用於(兩種語言),如果你有函數定義爲inline。然後你必須有兩個宏,一個用於內聯定義,你可以在每個看到該函數的頭文件中調用它。

此外,你必須有一個只在一個.c或.cpp文件中調用的第二個宏爲你做「實例化」。這裏的C或C++語法可能有點不同。

在C這應該是這個樣子

#define REGISTER(ns, id, type)           \ 
     inline Inst* type##Activate() { return new type(); }     \ 
     extern bool type##temp 

    #define INSTANTIATE(ns, id, type)          \ 
     Inst* type##Activate();            \ 
     bool type##temp = RegisterType(ns << 8 | id, &type##Activate)