Article directory
Function Description
Used to get how many arguments were actually passed to the variadic macro.
COUNT_ARGS(1, 2, 3)
, filled in 3 parameters, the return value is 3COUNT_ARGS("Hello", 'a', 3.14, 4)
, filled in 4 parameters, the return value is 4COUNT_ARGS(1)
, we filled in 1 parameter, and the return value is 1
accomplish
#define __COUNT_ARGS(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, N, ...) N
#define COUNT_ARGS(...) __COUNT_ARGS(, ##__VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
- The __COUNT_ARGS macro defines a macro with multiple parameters, where _0 to _20 are placeholder parameters, and N represents the number of parameters.
- The __COUNT_ARGS macro uses the feature of variable parameter macros, and converts the parameter sequence into a comma-separated parameter list through ##.
- The COUNT_ARGS macro defines a variadic macro that uses the __COUNT_ARGS macro to count the number of arguments.
- The COUNT_ARGS macro handles the case of no arguments by adding an empty argument (,) to avoid compilation errors.
- The COUNT_ARGS macro can accept up to 20 parameters, if more than 20 parameters, only the first 20 parameters will be counted.
...
the role of
...
is a variable parameter macro syntax, which means that any number of parameters can be accepted. In a macro definition, ...
indicates the end of the list of parameters that can be used in the definition of the macro.
__VA_ARGS__
the role of
__VA_ARGS__
is a special macro that represents a placeholder for variable arguments. In a macro definition,__VA_ARGS__
will be replaced by the actual parameters passed to the macro. It can be used to pass variable arguments to other macros or functions.
##__VA_ARGS__
the role of
##__VA_ARGS__
is a special syntax used in variadic macros. Its function is to remove the comma connector of variable parameters during macro expansion to avoid redundant commas. This is useful in some cases, especially when the macro's argument list is empty.
When we COUNT_ARGS
pass no parameters to , __VA_ARGS__
the value of is empty, , ##__VA_ARGS__
and this part will be deleted. Here is the syntax using ##
, when is an empty string, it will be deleted together __VA_ARGS__
with the initial .,
analyze
#define __COUNT_ARGS(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, N, ...) N
This macro requires at least 22 parameters to be passed, and the return value is the first 22
parameter.
If it exceeds the 22nd parameter, it will be digested by ... and return the 22nd parameter.
In fact, the essence of this macro is to use to occupy the place first 20, 19, ... 1, 0
, and every time an additional parameter is added, the rightmost number will be squeezed out.
Add one parameter, 0 will be squeezed out, return the 22nd parameter is 1,
add two parameters, 0 and 1 will be squeezed out, return the 22nd parameter is 2 and
so on
COUNT_ARGS(2, 4, 5)
COUNT_ARGS(2, 4, 5) expands to
__COUNT_ARGS(, 2, 4, 5, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
Passed 25 parameters to __COUNT_ARGS
, and then we will correspond to __COUNT_ARGS
the in :形参
The function of the __COUNT_ARGS macro is to return the 22nd parameter of the actual parameter. In fact, __COUNT_ARGS passed 25 parameters, so the macro only returns the 22nd parameter.3
No arguments COUNT_ARGS()
COUNT_ARGS() expands to become
__COUNT_ARGS(, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
There are 22 parameters passed to __COUNT_ARGS
, and then the passed parameters are __COUNT_ARGS
in one-to-one correspondence with the formal parameters in:
The function of the __COUNT_ARGS macro is to return the 22nd parameter of the actual parameter. Actually, __COUNT_ARGS passed 22 parameters, so this macro only returns the 22nd parameter 22 parameters are0
More than 22 parameters
Also note that the number of incoming parameters cannot exceed 22. If more than 22 parameters are passed in, this macro will return the parameter value of the 22nd parameter.
For example
COUNT_ARGS(c)
After macro expansion is
(, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 46, 76, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
Passed 44 parameters to __COUNT_ARGS
, and then we will correspond to __COUNT_ARGS
the in :形参
The function of the __COUNT_ARGS macro is to return the 22nd parameter of the actual parameter. The actual __COUNT_ARGS passed 44 parameters, so the macro only returns the 22nd parameter.46
So when the number of parameters exceeds 22, no matter how many parameters there are, N always corresponds to the value of the 22nd parameter.
example
#include <stdio.h>
#define __COUNT_ARGS(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, N, ...) N
#define COUNT_ARGS(...) __COUNT_ARGS(, ##__VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
int main(int argc, char *argv[])
{
int count1 = COUNT_ARGS(); // count1 = 0
int count2 = COUNT_ARGS(1, 2, 3); // count2 = 3
int count3 = COUNT_ARGS(1, 2, 3, 4, 5, 6, 7); // count3 = 7
int count4 = COUNT_ARGS("Hello", 'a', 3.14); // count4 = 3
int count5 = COUNT_ARGS(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20); // count5 = 20
int count6 = COUNT_ARGS(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 46, 76); // count6 = 20
printf("count1 = %d\n", count1);
printf("count2 = %d\n", count2);
printf("count3 = %d\n", count3);
printf("count4 = %d\n", count4);
printf("count5 = %d\n", count5);
printf("count6 = %d\n", count6);
return 0;
}
result print
count1 = 0
count2 = 3
count3 = 7
count4 = 3
count5 = 20
count6 = 46