2013-10-13 85 views
1

我在同一時間試圖定義和聲明一些全局C++常量定義C++數組:聲明,並在同一時間

constants.h

#ifdef DEFINE_CONSTANTS 
#define DECLARE_CONSTANT(DECL_, VAL_) extern DECL_ = VAL_ 
#else 
#define DECLARE_CONSTANT(DECL_, VAL_) extern DECL_ 
#endif 

namespace Constants { 
    DECLARE_CONSTANT(const char LABEL[], "SomeText"); 
    DECLARE_CONSTANT(const int REQUEST_TIMEOUT_MS, 5000); 
}; 

常數。 CPP

#define DEFINE_CONSTANTS 
#include "constants.h" 
#undef DEFINE_CONSTANTS 

在使用常量我只是包括所有其他文件constants.h

現在,如果我不使用數組初始值設定項,上述工作就好了。然而,當我嘗試做這樣的事情:

DECLARE_CONSTANT(const int ARRAY[], {0,1,2}); 

編譯 constants.cpp當我因爲在初始化逗號錯誤「混淆」的預處理器,以爲有太多的參數DECLARE_CONSTANT(確切的錯誤取決於編譯器)。

有處理這個問題的竅門嗎?其他解決方案也很受歡迎。

+0

你爲什麼使用預處理器。 C++是類型安全的,並有更好的選擇 –

+0

@EdHeal,請提出您的解決方案 –

+1

我還沒有得到什麼你想要實現的線索 –

回答

1

你在做什麼是過早的優化,導致過早的悲觀化。

  • 這是一個優化,因爲常量的內存只在一個編譯單元中分配。確實如此,對於像常量這樣的小常量,使用變量的指針實際上可能大於常量本身(比如在64位體系結構上!)。

  • 這是一個悲觀,因爲整型常量不能用於這種情況,它們是外部常量變量。他們將不會受到不斷傳播等你的代碼將是和將執行更糟

你想要什麼簡單地說就是:

const char LABEL[] = "Some text"; 
const int REQUEST_TIMEOUT_MS = 5000; 

那些具有本地聯動。是的,如果在多個地方使用LABEL,它將被複制到內存中,並且可執行文件的轉儲將顯示它。

非預處理解決方案需要一個inline功能,這是因爲它們不受單一定義規則:

inline const char * LABEL() { return "Some text"; } 
inline const int * ARRAY() { static const int array[] = {0,1,2}; return array; } 
const int REQUEST_TIMEOUT_MS = 5000; 

那些不會導致重複,除非你採取的REQUEST_TIMEOUT_MS地址在多個編譯單位。

6

這是因爲預處理器非常愚蠢,並且對C或C++的語法或結構一無所知。所以它認爲{0,1,2}是這個宏的三個不同的論點。

您可能能夠使用variadic macros這個雖然:

#define DECLARE_CONSTANT(DECL_, ...) extern DECL_ = __VA_ARGS__ 
+0

Joachim,雖然你幾乎完美地回答我的問題,@ KubaOber的回覆最終更好地契合我的實際需求。我的壞 - [只是我所要求的,但它不是我想要的](http://www.poppyfields.net/filks/00227.html):) –

+0

@malenkiy_scot沒關係,別擔心。 :) –

0

你需要

#define VALUE(...) __VA_ARGS__ 

,然後你可以使用

DECLARE_CONSTANT(const int ARRAY[], VALUE({0,1,2})); 

(勒夫的回答對你更容易具體情況,我的是比較一般的)