【发布时间】:2021-05-10 11:43:04
【问题描述】:
我是 C 的新手,如果这个问题变得微不足道,我很抱歉。我已经使用宏(现在)编写了一个项目结构初始化,它接受一个方法和一个字符串数组作为方法参数。最后一个参数的初始化会引发有关标量初始化程序中元素过多的警告。
item 是一个包含名称、方法和方法参数的小结构。如您所见,最后一个字段被声明为字符串数组。
// Definition of mcl_item; aka. mitem
struct mcl_item {
char *name;
void (*method)(char *args[]);
char **args;
};
#define mitem struct mcl_item
// Create a new mitem (user will use item and item0 macros instead)
mitem new_mitem(char name[MAX_STRLEN], void (*method)(char **), int n, char *arg, ...) {
// return simple mitem without arguments allocation
return((mitem){
.name = name,
.method = method,
.args = 0
});
}
这就是我的宏的样子,这也是我认为标量初始化应该起作用的:
// Define arguments amount by a macro
#define ARGSN(...) (int)(sizeof((char *){__VA_ARGS__})/sizeof(char *))
// Overload new_mitem() to avoid taking n parameter storing generated size
#define NEW_MITEM(name, method, ...) \
new_mitem(name, method, ARGSN(__VA_ARGS__), (char *){__VA_ARGS__})
// Top level macro for creating item with arguments
#define item(name, method, ...) NEW_MITEM(name, method, __VA_ARGS__)
// Top level macro for creating item without arguments
#define item0(name, method) NEW_MITEM(name, method, 0)
然后在主程序内部初始化项目并访问它们。
// Boilerplate methods used by items
void hello(char *args[]);
void extend(char *args[]);
int main() {
// initialize items
mitem item1 = item("extend", &extend, "Charlie", "Delta");
mitem item2 = item0("hello", &hello);
// access item1
printf("Accessing item: %s\n", item1.name);
item1.method(item1.args);
// access item2
printf("Accessing item: %s\n", item2.name);
item2.method(item2.args);
return(0);
}
// Boilerplate methods definitions
void hello(char *args[]) {
char name[MAX_STRLEN] = "Bob";
if (!args[0]) {
strcpy(name, args[0]);
}
printf("Hello %s!\n", name);
}
void extend(char *args[]) {
hello(args);
printf("Welcome %s.\n", args[1]);
}
带有-E标志预编译的gcc响应:
<source>:43:91: warning: excess elements in scalar initializer
43 | struct mcl_item item1 = new_mitem("extend", &extend, (int)(sizeof((char *){"Charlie", "Delta"})/sizeof(char *)), (char *){"Charlie", "Delta"});
| ^~~~~~~
<source>:43:91: note: (near initialization for '(anonymous)')
<source>:43:138: warning: excess elements in scalar initializer
43 | struct mcl_item item1 = new_mitem("extend", &extend, (int)(sizeof((char *){"Charlie", "Delta"})/sizeof(char *)), (char *){"Charlie", "Delta"});
| ^~~~~~~
<source>:43:138: note: (near initialization for '(anonymous)')
【问题讨论】:
-
是的,对不起。我想这就是你现在所需要的。
-
只需使用 -E 选项并查看预处理代码 godbolt.org/z/Mcnnvz 。然后开始相应地改变你的宏
-
不过,我看不出这个初始化有什么问题,为什么“Delta”错了:
struct mcl_item item1 = new_mitem("extend", &extend, (int)(sizeof((char *){"Charlie", "Delta"})/sizeof(char *)), (char *){"Charlie", "Delta"});
标签: arrays c string initialization