从常量查找表初始化常量

时间:2016-12-03 10:42:04

标签: c const initializer

我有一个常量查找表

static const uint32_t lut [] = {0, 20, 100, 350, 560};

我有一个结构

typedef struct {
    uint32_t value;
    const char * name;
} strct_t;

我想创建全局该结构的常量实例

const struct_t def_myname = {
    .value = lut[DEF_MYNAME_ID],
    .name = "myname",
};

但我需要在其他地方定义DEF_MYNAME_ID,所以我在一些头文件中有这个

#define DEF_MYNAME_ID 3

由于此错误initializer element is not constant

,因此无法编译

stackoverflow中有多个问题询问如何处理initializer element is not constant,但没有一个问题可以满足我的需求。

有办法怎么做?例如,将lut定义为宏?我不需要在其他地方使用它。

是否有像

这样的东西
#define LUT(a) ...

usabele as const初始化程序?

2 个答案:

答案 0 :(得分:1)

当然,宏可以做到这一点。 这实际上是一个更安全的代码,如果你选择一个超出范围的索引,它就不会编译。

首先我们定义字典

#define _val0 0
#define _val1 20
#define _val2 100
#define _val3 350
#define _val4 560

现在我们需要一个PRIMITIVE_CAT来强制扩展宏LUT的参数。

#define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__

最后,LUT

#define LUT(X) PRIMITIVE_CAT(_val, X)

现在你的代码。

#define DEF_MYNAME_ID 3
const struct_t def_myname = {
    .value = LUT(DEF_MYNAME_ID),
    .name = "myname",
};

答案 1 :(得分:0)

我认为你大部分都不走运,至少在普通的C上,因为即使以下也不会编译为静态初始化器:

int v = ((uint32_t[]) { 10, 20, 30, 40, 50 })[3];

FWIW,这没关系:

static const uint32_t *pv = lut + DEF_MYNAME_ID;

就像这样(基本上是一样的):

static const uint32_t *pv = &(lut[DEF_MYNAME_ID]);

另外,在C ++中,你的整个案例会很好。