I need to define a table that contain some values of variable lengths. I preferably want to declare it in one go since it's related to constants that will never change. I am checking if I can avoid a dynamic solution i.e. using malloc and set it up in code.
The code below will only serve as pseudo-code of what I want to achieve. It does not work. i.e.
typedef struct myelems {
char* name;
int count1;
int** values1;
int count2;
int** values2;
} myelems;
myelems arr[] = {
{"a", 3, {1, 2, 3}, 1, {42} },
{"b", 2, {123, 321}, 3, {99, 88, 77} },
// other elements here. . .
{"x", 0, NULL, 0 , NULL}
};
In this example "a" will contain 3 entries in values1 and 1 entry in values2 such that
arr[0].values1[0] = 1
arr[0].values1[1] = 2
arr[0].values1[2] = 3
arr[0].values2[0] = 42
"b" will contain 2 entries in values1 and 3 in values2 such that
arr[1].values1[0] = 123
arr[1].values1[1] = 321
arr[1].values2[0] = 99
arr[1].values2[1] = 88
arr[1].values2[2] = 77
and "x" have 0 entries in both values1 and values2
I hope this is not a silly question but I just can't find if it is not supported or if it is... if it is how should I do it?
Thanks for anything!
CodePudding user response:
If compound literals are an option you can:
#include <stdio.h>
typedef struct myelems {
char* name;
int count1;
int* values1; // Notice a single star
int count2;
int* values2; // Notice a single star
} myelems;
int main(void)
{
myelems arr[] = {
{"a", 3, (int[]){1, 2, 3}, 1, (int[]){42}},
{"b", 2, (int[]){123, 321}, 3, (int[]){99, 88, 77}},
// other elements here. . .
{"x", 0, NULL, 0 , NULL}
};
}
Your approach seems a bit dangerous (prone to errors) because you need to hardcode the number of elements of the array in count1
and count2
. Let the compiler count for you, with a little help of the preprocessor:
#define MAKE_INTS(...) \
sizeof((int[]){__VA_ARGS__}) / sizeof(int), (int[]){__VA_ARGS__}
int main(void)
{
myelems arr[] = {
{"a", MAKE_INTS(1, 2, 3), MAKE_INTS(42)},
{"b", MAKE_INTS(123, 321), MAKE_INTS(99, 88, 77)},
// other elements here. . .
{"x", 0, NULL, 0 , NULL}
};
}
MAKE_INTS(1, 2, 3)
expands to 3, (int[]){1, 2, 3}
.