The effort to implement varargs is indeed significant compared to other approaches. But I think there is even a simpler design than the one shown in the article. Why not just passing an array of void pointers and a count? Storing pointers to variables works perfectly fine (e.g. void* array[] = {&my_float, &my_int, &my_double}). All pointers have the same size regardless of what they point to, so a void* array can hold pointers to any type without issues. The array can even be created inline (in C99) or on the stack without dynamic allocation. That's how I do it in my Micron language.
The effort to implement varargs is indeed significant compared to other approaches. But I think there is even a simpler design than the one shown in the article. Why not just passing an array of void pointers and a count? Storing pointers to variables works perfectly fine (e.g. void* array[] = {&my_float, &my_int, &my_double}). All pointers have the same size regardless of what they point to, so a void* array can hold pointers to any type without issues. The array can even be created inline (in C99) or on the stack without dynamic allocation. That's how I do it in my Micron language.
There is current interest in adding __VA_COUNT__ https://github.com/llvm/llvm-project/issues/155234
The __VA_TAIL__ proposal might simplify the map macros (as well as expanding more efficiently) https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3307.htm