检查整数常量在编译时具有不同的值

时间:2012-08-09 23:20:07

标签: c++ compilation

我的问题如下。我有大量的静态const整数作为标识符。出于这个原因,我想知道是否有可能在编译时检查是否存在多个具有相同值的常量(某种静态断言...)。

我不想使用枚举,因为这些常量是在不同的模块中定义的,我不希望它们具有所有这些常量的长枚举(并且其中一些不相互关联)。 / p>

这里有一个基本的例子:

// module: foo.h
const uint32_t ELEMENT_TYPE_FOO_X = 46;
const uint32_t ELEMENT_TYPE_FOO_Y = 51;
...

// module: boo.h
const uint32_t ELEMENT_TYPE_BOO_C = 21;
const uint32_t ELEMENT_TYPE_BOO_D = 51;

错误:ELEMENT_TYPE_FOO_Y和ELEMENT_TYPE_BOO_D具有相同的值。

我根本不是专家,我想到的唯一能够检测到这个错误的是模板专业化。

template<uint32_t N>
struct element_traits {
};

template<ELEMENT_TYPE_FOO_X> {
    enum { value = ELEMENT_TYPE_FOO };
};

但它似乎是一个复杂的解决方案。我不知道是否有更优雅/更好的解决方案。到目前为止我还没有找到任何东西。

提前致谢。

3 个答案:

答案 0 :(得分:6)

你当然可以使用宏来做到这一点:

#define UNIQUE_CONSTANT(variable, value) \
  const uint32_t variable = value; \
  bool constant_val_##value = value;

如果两次使用相同的值,则会出现多重定义错误。

(从技术上讲,这将在链接时检测错误,而不是编译时间。)

答案 1 :(得分:0)

基于Keith的解决方案。我可以“检查”常量具有调试构建的唯一值,并跳过它以进行发布构建。

#ifdef DEBUG
#define DEFINE_UNIQUE_CONSTANT(variable, value) \
    const uint32_t variable = value;            \
    uint32_t constant_val_##value = value;
#else
#define DEFINE_UNIQUE_CONSTANT(variable, value) \
    const uint32_t variable = value;
#endif

答案 2 :(得分:0)

如果大量常量必须不同并且必须在不同的源文件中定义,那么您可以通过这种方式生成它们,例如,从包含文件名和相应常量名称的文件开始,并在每次构建时生成其余部分。

输入文件:

[foo.h]
ELEMENT_TYPE_FOO_X
ELEMENT_TYPE_FOO_Y

[boo.h]
ELEMENT_TYPE_BOO_C
ELEMENT_TYPE_BOO_D

剧本:

#!/usr/bin/env python
from ConfigParser import SafeConfigParser
from itertools import count

config = SafeConfigParser(allow_no_value=True)
config.optionxform = lambda x: x # use names as-is
config.read('input.cfg')

counter = count(1)
for filename in config.sections():
    with open(filename, 'w') as f:
         for (name, _), i in zip(config.items(filename), counter):
             f.write("const uint32_t %s = %s;\n" % (name, i))