I am new to C, so sorry if this problem turns trivial. I have written a item structure initialization using macros (for now) which takes in a method and an array of strings to be used as the method arguments. Initialization of the last argument is throwing warning about excess of elements in scalar initializer.
The item is a little structure holding name, method, and method arguments. As you can see, the last field is declared to be an array of strings.
// 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
});
}
This is how my macros looks like, here also it looks for me that the scalar initialization should work:
// 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)
And then inside of the main procedure I initialize the items and access them.
// 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]);
}
gcc response with -E flag precompilation:
<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)')
struct mcl_item item1 = new_mitem("extend", &extend, (int)(sizeof((char *){"Charlie", "Delta"})/sizeof(char *)), (char *){"Charlie", "Delta"});