1

我正在尝试同时定义和声明一些全局 C++ 常量:

常量.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 的参数太多(确切的错误取决于编译器)。

有什么技巧可以解决这个问题吗?也欢迎其他解决方案。

4

3 回答 3

6

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

不过,您也许可以为此使用可变参数宏

#define DECLARE_CONSTANT(DECL_, ...) extern DECL_ = __VA_ARGS__
于 2013-10-13T16:17:01.943 回答
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除非您在多个编译单元中获取地址,否则这些不会导致重复。

于 2013-10-13T20:00:34.610 回答
0

你需要

#define VALUE(...) __VA_ARGS__

然后你可以使用

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

(对于您的具体情况,Joachim 的回答更容易,我的更一般)

于 2013-10-13T16:31:41.713 回答