Count the number of parameters in a variable method call to variable C

When using va_start (), va_arg (), and va_end () to read the parameters passed to the method, is there a way to calculate how many arguments exist?

According to the man page, if you call va_arg () too many times, you get "random errors":

If there is no next argument, or if the type is incompatible with the type of the actual next argument (as is advanced according to the default arguments), random errors will occur.

+6
c gcc variadic-functions
source share
3 answers

Not. the Variable Argument function (for example, printf ) should “know” when it stops looking for more arguments.

printf knows the number %d , %s and other characters in the format string.

Other functions sometimes use Sentinel values:

 sumValues(1, 3, 5, 7, 6, 9, -1); // will add numbers until it encounters a -1 

Other functions may have a number of parameters specified in front:

 AddNames(4, "Bill", "Alice", "Mike", "Tom"); 
+11
source share

Here's a pretty fun trick that lets you create what you want with the C99 variable macros:

PP_NARG ()
Returns the number of arguments contained in __VA_ARGS__

You can use this to write a macro that flips your real function, which adds a count to the front of the arguments of the real function.

See also this question . However, classic approaches are probably even more sensible for a year or three!


Code, so this answer is useful even without a Usenet archive ...

 /* The PP_NARG macro returns the number of arguments that have been * passed to it. */ #define PP_NARG(...) \ PP_NARG_(__VA_ARGS__,PP_RSEQ_N()) #define PP_NARG_(...) \ PP_ARG_N(__VA_ARGS__) #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 #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 
+8
source share

There are two ways to find out how many arguments were passed. First, you can specify one of the function parameters (for example, printf ). Another way is to have a sentinel value at the end of your list — for example, you could stop at the NULL argument.

You can use va_copy if you choose the second method, but still want to calculate the parameters before deciding what to do with them.

+5
source share

All Articles