在编译时在 C 中生成嵌套常量数组
Generate nested constant arrays in C at compile time
我试图在编译时在 C (C99) 中生成一个大的常量查找 table,查找的每个条目 table 都有一个指向另一个常量数组的指针。我希望能够一次构建所有这些数组,但这是不可能的,因为大括号初始化程序不能用于指针。是否有一些预处理器宏或其他技巧可以用来定义 "anonymous" 数组或类似的东西,以便我可以将它们包含在嵌套数据结构中?
我在下面创建了一个示例,展示了我目前正在做的事情,以及我正在尝试做的事情。
typedef enum {
RED = 0,
GREEN,
BLUE,
PURPLE,
YELLOW
} colours_t;
typedef struct {
const char *name;
const size_t number_of_preferences;
const colours_t *ordered_preferences;
} colour_preferences_t;
// this way works, but is tedious
const colours_t bob_preferences[] = {RED, GREEN};
const colours_t alice_preferences[] = {BLUE, PURPLE, YELLOW};
const colours_t eve_preferences[] = {YELLOW, RED};
const colour_preferences_t array_of_preferences[3] = {
{"Bob", 2, bob_preferences},
{"Alice", 3, alice_preferences},
{"Eve", 2, eve_preferences}
};
// this is how I'd like to do it (but it isn't valid)
const colour_preferences_t array_of_preferences_invalid[3] = {
{"Bob", 2, {RED, GREEN}},
{"Alice", 3, {BLUE, PURPLE, YELLOW}},
{"Eve", 1, {YELLOW, RED}},
};
更新:感谢下面的回答,我找到了一个解决方案。使用 varadic 宏,我什至可以放弃明确输入大小:
#define PREFERENCE_LIST(...) sizeof((colours_t[]) { __VA_ARGS__ })/sizeof(colours_t), (colours_t[]){ __VA_ARGS__ }
const colour_preferences_t array_of_preferences_short[3] = {
{"Bob", PREFERENCE_LIST(RED, GREEN)},
{"Alice", PREFERENCE_LIST(BLUE, PURPLE, YELLOW)},
{"Eve", PREFERENCE_LIST(YELLOW, RED)}
};
您需要创建对象,并且指向该对象的指针必须是该字段的初始值设定项。您可以使用 复合文字
将其存档
const colour_preferences_t array_of_preferences_invalid[3] = {
{"Bob", 2, ( const colours_t[]){RED, GREEN}},
{"Alice", 3, (const colours_t[]){BLUE, PURPLE, YELLOW}},
{"Eve", 1, (const colours_t[]){YELLOW, RED}},
};
它应该可以使用这样的复合文字:
const colour_preferences_t array_of_preferences_invalid[3] = {
{"Bob", 2, (colours_t[]){RED, GREEN}},
{"Alice", 3, (colours_t[]){BLUE, PURPLE, YELLOW}},
{"Eve", 1, (colours_t[]){YELLOW, RED}},
};
您可以阅读有关复合文字的详细信息here
我试图在编译时在 C (C99) 中生成一个大的常量查找 table,查找的每个条目 table 都有一个指向另一个常量数组的指针。我希望能够一次构建所有这些数组,但这是不可能的,因为大括号初始化程序不能用于指针。是否有一些预处理器宏或其他技巧可以用来定义 "anonymous" 数组或类似的东西,以便我可以将它们包含在嵌套数据结构中?
我在下面创建了一个示例,展示了我目前正在做的事情,以及我正在尝试做的事情。
typedef enum {
RED = 0,
GREEN,
BLUE,
PURPLE,
YELLOW
} colours_t;
typedef struct {
const char *name;
const size_t number_of_preferences;
const colours_t *ordered_preferences;
} colour_preferences_t;
// this way works, but is tedious
const colours_t bob_preferences[] = {RED, GREEN};
const colours_t alice_preferences[] = {BLUE, PURPLE, YELLOW};
const colours_t eve_preferences[] = {YELLOW, RED};
const colour_preferences_t array_of_preferences[3] = {
{"Bob", 2, bob_preferences},
{"Alice", 3, alice_preferences},
{"Eve", 2, eve_preferences}
};
// this is how I'd like to do it (but it isn't valid)
const colour_preferences_t array_of_preferences_invalid[3] = {
{"Bob", 2, {RED, GREEN}},
{"Alice", 3, {BLUE, PURPLE, YELLOW}},
{"Eve", 1, {YELLOW, RED}},
};
更新:感谢下面的回答,我找到了一个解决方案。使用 varadic 宏,我什至可以放弃明确输入大小:
#define PREFERENCE_LIST(...) sizeof((colours_t[]) { __VA_ARGS__ })/sizeof(colours_t), (colours_t[]){ __VA_ARGS__ }
const colour_preferences_t array_of_preferences_short[3] = {
{"Bob", PREFERENCE_LIST(RED, GREEN)},
{"Alice", PREFERENCE_LIST(BLUE, PURPLE, YELLOW)},
{"Eve", PREFERENCE_LIST(YELLOW, RED)}
};
您需要创建对象,并且指向该对象的指针必须是该字段的初始值设定项。您可以使用 复合文字
将其存档const colour_preferences_t array_of_preferences_invalid[3] = {
{"Bob", 2, ( const colours_t[]){RED, GREEN}},
{"Alice", 3, (const colours_t[]){BLUE, PURPLE, YELLOW}},
{"Eve", 1, (const colours_t[]){YELLOW, RED}},
};
它应该可以使用这样的复合文字:
const colour_preferences_t array_of_preferences_invalid[3] = {
{"Bob", 2, (colours_t[]){RED, GREEN}},
{"Alice", 3, (colours_t[]){BLUE, PURPLE, YELLOW}},
{"Eve", 1, (colours_t[]){YELLOW, RED}},
};
您可以阅读有关复合文字的详细信息here