C中的编译时查找表(C11)

时间:2014-01-29 12:33:43

标签: c arrays c11

我想知道C是否具有语言或编译器(gcc)中的功能,以允许我将const初始化数组转换为const结构的编译时查找表。这是我的情况改造:

typedef struct Entry {
    bool alive;
    float a, b, c;
    double d, e, f;
} Entry;

现在,我有一个数组声明:

extern const int entryCount; // Assume this is equal to an enum value.
extern const Entry entries[entryCount];

如上所述,数组中的位置相对于枚举常量,该常量是放入入口结构的数据的特征。假设entryCount初始化为枚举中的条目数。 这是我的问题所在,当我像这样初始化这个数组时:

const int entryCount = ENTRY_COUNT;
const Entry entries[entryCount] = {
    { false, 0.1f, 0.2f, 0.0f, 1.0, 1.0, -1.0 },
    ...
};

它们是在编译时创建的,并且在运行时没有创建开销吗?或者它是否在运行时分配在内存中?因为价值永远不会改变。我怎样才能在C中实现这个目标?

2 个答案:

答案 0 :(得分:3)

如果您需要定义数组的所有组件都是C标准意义上的编译时常量,那么您可以实现所需。唯一不是你所提供的是entryCount。它必须enum常量。

然后,您必须将该数组作为全局(文件范围)数组。如果要通过包含文件(.h)在不同的.c文件(所谓的编译单元)中包含相同的数组,则必须将其声明为static,这样多个定义在不会发生冲突时你链接程序。

enum { entryCount = ENTRY_COUNT };
static const Entry entries[entryCount] = {
    { false, 0.1f, 0.2f, 0.0f, 1.0, 1.0, -1.0 },
    ...
};

static这意味着这会创建一个变量,其生命周期跨越程序的整个执行,但不会生成此变量的外部符号。如果您将变量的#include定义为几个.c文件,则必须这样做。

这没有运行时开销,现在应该通过优秀的优化编译器来优化对entries[4].d之类的条目的访问。

这只有一个缺点,即它复制了所有单元中阵列的生成,即使它不需要也在那里。避免这种情况的一种方法是将宏扩展为像这样的复合文字

#define ENTRIES (const Entry [entryCount]){        \
    { false, 0.1f, 0.2f, 0.0f, 1.0, 1.0, -1.0 },   \
    ...                                            \
}

const比编译器留有余地只分配一次该数组(如果有的话)并且将避免在完全不使用该功能的编译单元中的额外副本。

答案 1 :(得分:0)

你可以全局定义一次(可能是.c文件中)和多次声明(在某些.h文件中包含的地方)。这是const没有区别。编译/加载到内存时将分配一次。