0

I have the following variadic macro, which counts the number of arguments passed to it at compile time:

#define NUMARGS(...) (sizeof((int[]){__VA_ARGS__}) / sizeof(int))

For example, the following example is equivalent to 4:

const int example = NUMARGS(3, 0, 2, 1); // = 4

I would like to do the same for array values:

const int example2 = NUMARGS( {3, 2}, {0, 1}, {4, 3} ); // = 3

Once this code is compiled, the variable is indeed set to 3. Nevertheless, gcc displays the following warning:

main.c:10:5: warning: braces around scalar initializer
  10 |     const int example2 = NUMARGS( {3, 2}, {0, 1}, {4, 3} );
     |     ^~~~~
main.c:10:5: note: (near initialization for ‘(anonymous)[0]’)
main.c:10:39: warning: excess elements in scalar initializer
  10 |     const int example2 = NUMARGS( {3, 2}, {0, 1}, {4, 3} );
     |                                       ^
main.c:1:38: note: in definition of macro ‘NUMARGS’
  23 | #define NUMARGS(...) (sizeof((int[]){__VA_ARGS__}) / sizeof(int))
     |                                      ^~~~~~~~~~~
main.c:10:39: note: (near initialization for ‘(anonymous)[0]’)
  10 |     const int example2 = NUMARGS( {3, 2}, {0, 1}, {4, 3} );
     |                                       ^
main.c:1:38: note: in definition of macro ‘NUMARGS’
  23 | #define NUMARGS(...) (sizeof((int[]){__VA_ARGS__}) / sizeof(int))
     |                                      ^~~~~~~~~~~
main.c:10:5: warning: braces around scalar initializer
  10 |     const int example2 = NUMARGS( {3, 2}, {0, 1}, {4, 3} );
     |     ^~~~~
main.c:10:5: note: (near initialization for ‘(anonymous)[1]’)
main.c:10:47: warning: excess elements in scalar initializer
  10 |     const int example2 = NUMARGS( {3, 2}, {0, 1}, {4, 3} );
     |                                               ^
main.c:1:38: note: in definition of macro ‘NUMARGS’
  23 | #define NUMARGS(...) (sizeof((int[]){__VA_ARGS__}) / sizeof(int))
     |                                      ^~~~~~~~~~~
main.c:10:47: note: (near initialization for ‘(anonymous)[1]’)
  10 |     const int example2 = NUMARGS( {3, 2}, {0, 1}, {4, 3} );
     |                                               ^
main.c:1:38: note: in definition of macro ‘NUMARGS’
  23 | #define NUMARGS(...) (sizeof((int[]){__VA_ARGS__}) / sizeof(int))
     |                                      ^~~~~~~~~~~
main.c:10:5: warning: braces around scalar initializer
  10 |     const int example2 = NUMARGS( {3, 2}, {0, 1}, {4, 3} );
     |     ^~~~~
main.c:10:5: note: (near initialization for ‘(anonymous)[2]’)
main.c:10:55: warning: excess elements in scalar initializer
  10 |     const int example2 = NUMARGS( {3, 2}, {0, 1}, {4, 3} );
     |                                                       ^
main.c:1:38: note: in definition of macro ‘NUMARGS’
  23 | #define NUMARGS(...) (sizeof((int[]){__VA_ARGS__}) / sizeof(int))
     |                                      ^~~~~~~~~~~
main.c:10:55: note: (near initialization for ‘(anonymous)[2]’)
  10 |     const int example2 = NUMARGS( {3, 2}, {0, 1}, {4, 3} );
     |                                                       ^
main.c:1:38: note: in definition of macro ‘NUMARGS’
  23 | #define NUMARGS(...) (sizeof((int[]){__VA_ARGS__}) / sizeof(int))
     |                                      ^~~~~~~~~~~

gcc does not offer to disable this warning, and, if I'm not mistaken, it is not needed here as it is only used in my macro to count variadic arguments.

How can I make sure that the error is not displayed anymore, hoping not to make the writing more cumbersome in the use of the macro (as this is of course the aim)?

Foxy
  • 980
  • 8
  • 17
  • Isn't the denomiator now `int[]` as well? – Neil Aug 19 '21 at 16:36
  • 2
    The type doesn't match the initializer in the second case, you'd need a `int[][2]` or something like that. No idea how to generalize – Mat Aug 19 '21 at 16:40
  • https://stackoverflow.com/questions/2124339/c-preprocessor-va-args-number-of-arguments – user3386109 Aug 19 '21 at 16:42
  • @Mat Indeed, this is what should be done, but then we lose the principle of this macro. – Foxy Aug 19 '21 at 16:50
  • @user3386109 The first solution on the page seems to work. I prefer my macro though, it's more sober, but doesn't seem to work (without warnings) for what I'm asking, I'll go with the proposed solution. Thank you. – Foxy Aug 19 '21 at 16:50
  • 1
    @Foxy Sounds good. I'll mark this as a duplicate to make it easier for future visitors to find that Q/A. – user3386109 Aug 19 '21 at 16:53

0 Answers0