If it receives less than 5 arguments, it should put 0 in the structure.
This can be solved by using compound literals. First we can create a macro with compound literals to determine the number of VA_ARGS, since there is no standard macro for that:
#define ARGS_N(...) (sizeof((int[]){ __VA_ARGS__ }) / sizeof(int))
This can be used to determine the number of items. In this case if there are exactly 5, the struct should be initialized with those values, otherwise it should be initialized to 0.
We can then use the above macro to create a conditional initializer list. Given some struct:
typedef struct
{
int a;
int b;
int c;
int d;
int e;
} test_t;
We could initialize instances of that struct through a custom method:
test_t t1 = TEST_INIT(1,2,3);
Which would be implemented as:
#define TEST_INIT(...) (ARGS_N(__VA_ARGS__)==5) ? (test_t){__VA_ARGS__} : (test_t){0}
Unfortunately some compilers (gcc) will whine about missing initializers since both paths of the conditions are expanded, even if only one is evaluated. In this case we can safely tell gcc to shut up:
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
Full program:
#include <stdio.h>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
typedef struct
{
int a;
int b;
int c;
int d;
int e;
} test_t;
#define ARGS_N(...) (sizeof((int[]){ __VA_ARGS__ }) / sizeof(int))
#define TEST_INIT(...) (ARGS_N(__VA_ARGS__)==5) ? (test_t){__VA_ARGS__} : (test_t){0}
int main (void)
{
test_t t1 = TEST_INIT(1,2,3);
test_t t2 = TEST_INIT(1,2,3,4,5);
printf("%d %d %d %d %d\n", t1.a, t1.b, t1.c, t1.d, t1.e);
printf("%d %d %d %d %d\n", t2.a, t2.b, t2.c, t2.d, t2.e);
}
#pragma GCC diagnostic pop
Output:
0 0 0 0 0
1 2 3 4 5