Reputation: 470
To get number of __VA__ARGS__
, I read this answer and it works. But I feel that PP_NARG_
is redundant, and I see no reason why PP_RSEQ_N
is a macro function. So I modify the code as below
#include <assert.h>
#define PP_RSEQ_N \
63,62,61,60, \
59,58,57,56,55,54,53,52,51,50, \
49,48,47,46,45,44,43,42,41,40, \
39,38,37,36,35,34,33,32,31,30, \
29,28,27,26,25,24,23,22,21,20, \
19,18,17,16,15,14,13,12,11,10, \
9,8,7,6,5,4,3,2,1,0
#define PP_NARG(...) \
PP_ARG_N(__VA_ARGS__,PP_RSEQ_N)
#define PP_ARG_N( \
_1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
_11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
_21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
_31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
_41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
_51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
_61,_62,_63,N,...) N
/* Some test cases */
int main() {
assert(PP_NARG(1,2,"yes",!)==4);
}
I get errors and notes.
main.c:24:33: error: macro "PP_ARG_N" requires 65 arguments, but only 5 given
assert(PP_NARG(1,2,"yes",!)==4);
^
It seems that in PP_NARG
, PP_RSEQ_N
is not expanded. But why? I know that with #
and ##
, macro will not be expanded, but this is not the case.
Also I want to know why PP_NARG_
is necessary in this answer , and why PP_RSEQ_N
is a macro function, not a normal macro(no arguments)?
Upvotes: 0
Views: 279
Reputation: 241671
The essential nature of macro calls is that macro arguments are not expanded in the macro call. The precise procedure is specified in the standard at §6.10.3.1.
- After the arguments for the invocation of a function-like macro have been identified, argument substitution takes place.
So the arguments to the macro are separated by the commas actually present in the token stream at that point, regardless of what the substituted argument might look like.
Once the arguments are collected, the uses of the macro parameters in the macro body are replaced with the arguments. In most cases, the arguments are expanded at this point, but (as you note) if the parameter is used as part of a #
or ##
expression, the argument is not macro-substituted for that use. Also, there is no requirement that a parameter be used at all in the macro body, so in such a case there will be no need to expand the argument at all.
Once the macro parameters have been replaced with the corresponding arguments and the #
and ##
operators are evaluated, the resulting token stream is passed back through the macro processor. It's during this rescan that any macros used in the body of the macro will be expanded.
Now, the author of PP_NARG
actually wanted to construct a macro call consisting of the original varargs arguments to PP_NARG
followed by the expansion of PP_RSEQ_N
. Since the expansion of the macro argument PP_RSEQ_N
won't take place until the expansion of the macro call it appears in, it's necessary to introduce an extra level of macro expansion; the PP_NARG_
macro is used to construct the call to PP_NARG
. (You could avoid this by not using PP_RSEQ_N
at all, instead putting the countdown directly in the call to PP_NARG
. But there are abundant reasons to avoid this solution; it's cleaner to add the extra level of macro substitution.)
The usual reason to define a macro like PP_RSEQ_N
as a function-like macro without arguments instead of a simple macro is to be able to pass around the name of the macro without it being expanded. That doesn't seem to be the case in this snippet, but it might be present elsewhere in the code from which the snippet was extracted.
Upvotes: 1