我(必须)使用 C 预处理器从某种配置表创建代码。目标是配置可以一目了然,每个设置(=数组名称和大小)只定义一次,并且应该很容易添加/删除配置项。
傻了,我需要这样的东西:
config table
no | size | buffer_name
0 300 Foo_0
1 280 Bar_1
应该创建这样的代码:
// first create the buffers
int Foo_0[300]
int Bar_1[280]
// then create a configuration the software will use.
#define NO_OF_ITEMS 2
// this array defines the sizes
const int bufferSizes[NO_OF_ITEMS] = {300, 280}
// this array defines the pointers to the buffers
const int* bufferPointers[NO_OF_ITEMS] = {Foo_0, Bar_1}
限制: 缓冲区(Foo_0 和 Bar_1)需要有单独的数组,不能是一个大数组——它们必须分配到多个内存区域。
我试图创建一个“配置宏”和一个“生成器宏”,但不知道如何“存储和调用”配置项,因为一个宏无法创建第二个宏。
CONFIG_CREATE (0, 300, Foo_0)
CONFIG_CREATE (1, 280, Bar_1)
CONFIG_GENERATE_BUFFER (0)
CONFIG_GENERATE_BUFFER (1)
// will create the buffers based on values above)
CONFIG_GENERATE_SIZES
// generates const int bufferSizes[NO_OF_ITEMS] = {300, 280}
CONFIG_GENERATE_POINTERS
// generates const int* bufferPointers[NO_OF_ITEMS] = {Foo_0, Bar_1}
所有其他方式都有冗余信息(例如:缓冲区定义和 bufferSizes 数组中的大小必须正确,特别是如果配置条目的数量变大,则有很大的错误空间。
我还通过 typedef 尝试了“经典”配置表,例如:
const configItems staticBufferConfiguration[] =
[0] = {300, Foo_0}
[1] = {280, Bar_1}
}
问题是,在这里我也必须单独创建缓冲区,并且它们需要与配置表中的大小相同。 我无法使用表中的大小来创建长度正确的缓冲区。 对长度使用宏也不是一个干净的解决方案,因为我仍然必须手动将正确的宏添加到正确的表中。如果配置变得更复杂并且有更多条目,则错误来源:
int Foo_0[FOO_0_LENGTH];
int Bar_1[BAR_1_LENGTH];
int BarXE_2[BARXE_2_LENGTH];
int BarXE_3[BARXE_3_LENGTH];
int BarXE_4[BARXE_4_LENGTH];
const configItems staticBufferConfiguration[] =
[0] = {FOO_0_LENGTH, Foo_0}
[1] = {BAR_1_LENGTH, Bar_1}
[2] = {BARXE_2_LENGTH, BarXE_2}
[2] = {BARXE_2_LENGTH, BarXE_3}
[3] = {BARXE_4_LENGTH, BarXE_4}
// can you spot the copy/paste mistake??
}
您可以使用x-macro概念:
#define TBL(f) \
/*size name*/ \
f(300, Foo_0) \
f(200, Bar_1) \
f(100, Baz_2) \
// ...
#define F1(size,name) int name[size];
TBL(F1)
#define F2(size,name) size,
const int bufferSize[] = { TBL(F2) };
#define F3(size,name) name,
const int* bufferPointers[] = { TBL(F3) };
这将生成扩展为以下代码:
int Foo_0[300]; int Bar_1[200]; int Baz_2[100];
const int bufferSize[] = { 300, 200, 100, };
const int* bufferPointers[] = { Foo_0, Bar_1, Baz_2, };
这个想法应该很容易解释。
您现在可以使用
NO_OF_ITEMS
获得sizeof
:
#define NO_OF_ITEMS (sizeof bufferSize / sizeof *bufferSize)