同时声明和定义C ++数组

时间:2013-10-13 16:12:31

标签: c++ c-preprocessor

我正在尝试同时定义和声明一些全局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);
};

constants.cpp 中:

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

在使用常量的所有其他文件中,我只包含 constants.h

现在,如果我不使用数组初始化器,上面的工作就可以了。但是,当我尝试做类似的事情时:

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

编译 constants.cpp 时出现错误,因为初始化程序中的逗号“混淆”预处理器,认为DECLARE_CONSTANT的参数太多(确切的错误取决于编译器)。 / p>

有没有办法解决这个问题?其他解决方案也欢迎。

3 个答案:

答案 0 :(得分:6)

这是因为预处理器非常愚蠢,对C或C ++的语法或结构一无所知。因此它将{0,1,2}视为宏的三个不同参数。

尽管如此,您可以使用variadic macros

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

答案 1 :(得分:1)

您正在做的是过早优化,导致过早的悲观情绪。

  • 这是一个优化,因为常量的内存只在一个编译单元中分配。这是真的,但对于小常量,如整数,使用变量时隐含的指针实际上可能大于常量本身(例如64位架构!)。

  • 这是一个悲观,因为整数常数不能这样使用,它们是外部常量变量。它们不会受到不断的传播等。您的代码将更大并将执行更糟

你想要的只是:

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

那些有本地联系。是的,如果您在多个地方使用LABEL,它将在内存中重复,并且可执行文件的strings转储将显示它。

非预处理器解决方案采用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的地址,否则这些不会导致重复。

答案 2 :(得分:0)

你需要

#define VALUE(...) __VA_ARGS__

然后你可以使用

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

(Joachim的答案对于你的具体案例更容易,我的答案更为一般)