C99 允许数组初始值设定项(除其他外)指定使用正整数指示符设置数组的哪个元素($6.7.8.6、$6.7.8.17),例如:
const char *foo[] = {[2] = "foo", [1] = "bar", [0] = "baz"};
我以前用它来制作一个枚举到字符串的表,如下所示:
enum {THING_FOO = 0, THING_BAR, THING_BAZ};
const char *table[] = {
[THING_FOO] = "foo",
[THING_BAR] = "bar",
[THING_BAZ] = "baz"
}
但是,我现在的工作要求是我的代码符合 c89。
我已经研究过预处理器魔法(例如在这里),但我需要字符串是任意的,而不是枚举符号的副本。
仅仅做是不够的
enum {THING_FOO = 0, THING_BAR, THING_BAZ};
const char *table[] = {"foo", "bar", "baz"};
因为我将来需要添加枚举元素。使用 c99 方法,这将导致表中出现 NULL 指针,如果它们出现问题,可以很容易地进行调试。如果我忘记使用这种方法更新字符串表,我会得到更难调试的段错误。如果无论如何我都必须记住偏移量,它也会破坏拥有符号的意义。
如果声明在一个函数中,我可以达到这样的预期效果:
enum {THING_FOO = 0, THING_BAR, THING_BAZ, NUM_THINGS};
void foo(void)
{
static const char *table[NUM_THINGS];
table[THING_FOO] = "foo";
table[THING_BAR] = "bar";
table[THING_BAZ] = "baz";
/* ... */
}
但是,至少对于gcc
,这并没有得到优化。
有没有办法在 c89 中声明这样的字符串表?(组装没问题。)