2013-10-13 33 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})); 

(勒夫的回答对你更容易具体情况,我的是比较一般的)