简体   繁体   English

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

[英]Compile-time lookup table in C (C11)

I was wondering if C had functionality within the language or compiler (gcc) to allow me to turn my const intialized array into a compile-time lookup table of const structs. 我想知道C是否具有语言或编译器(gcc)中的功能,以允许我将const的初始化数组转换为const结构的编译时查找表。 Here is a remodel of my situation: 这是我的情况改造:

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

Now, I have a declaration for the array: 现在,我有一个数组的声明:

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

As stated, the position in the array are relative to an enum constant that is characteristic of the data put into the entry structure. 如上所述,数组中的位置相对于枚举常量,该常量是放入入口结构的数据的特征。 Assume that entryCount is initialized to the number of entries in the enumeration. 假设entryCount初始化为枚举中的条目数。 Here is where my question is, when I initialize this array like so: 这是我的问题所在,当我初始化这个数组时:

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

Are they created at compile-time and create no overhead in runtime? 它们是在编译时创建的,并且在运行时不会产生任何开销吗? Or is it allocated in memory at runtime? 或者它是否在运行时分配在内存中? Because the values will never change. 因为价值永远不会改变。 How can I achieve this in C? 我怎样才能在C中实现这一目标?

You can achieve what you want if all of the components that you need to define your array are compile time constants in the sense of the C standard. 如果您需要定义数组的所有组件都是C标准意义上的编译时常量,那么您可以实现所需。 The only thing that isn't of what you have given is entryCount . 唯一不是你给出的东西是entryCount It really must be an enum constant. 必须是一个enum常数。

Then you'd have to put that array as a global (file scope) array. 然后,您必须将该数组作为全局(文件范围)数组。 If you want to include the same array through an include file (.h) in different .c files (so-called compilation units) you'd have to declare it static , such that multiple definitions wouldn't conflict when you link the program. 如果要通过包含文件(.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 here means that this creates a variable that has a lifetime that spans the whole execution of the program, but that no external symbol for this variable is generated. static here意味着这将创建一个变量,该变量具有跨越整个程序执行的生命周期,但不会生成此变量的外部符号。 This is necessary if you #include the same definition of a variable into several .c files. 如果#include相同的变量定义为几个.c文件,这是必要的。

This has no runtime overhead and access to an entry such as entries[4].d should nowadays be optimized away by a good optimizing compiler. 这没有运行时开销,并且现在应该通过良好的优化编译器来优化对诸如entries[4].d类的entries[4].d访问。

This has only one drawback, in that it duplicates the generation of the array in all units, even if it is not needed, there. 这只有一个缺点,即它在所有单元中复制阵列的生成,即使在那里不需要也是如此。 One way to avoid that would be a macro that expands to a compound literal like this 避免这种情况的一种方法是将宏扩展为这样的复合文字

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

The const than leaves leeway to the compiler to allocate that array only once (if any) and will avoid an extra copy in compilation units that don't use that feature at all. const只留下编译器的余地,只分配一次该数组(如果有的话),并避免在完全不使用该功能的编译单元中添加额外的副本。

You can define the array globally once (in a .c file, probably) and declare it multiple times (in some .h file included everywhere). 您可以全局定义一次该数组(可能在.c文件中)并多次声明它(在某些.h文件中包含在任何地方)。 That it is const makes no difference. 这是const没有区别。 It will be allocated once when compiling/loading into memory. 编译/加载到内存时将分配一次。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM