I have a variadic function:
print_n_integers(7, 1, 2, 3, 4, 5, 6, 7);
int print_n_integers( unsigned int count, ... )
{
// use va_start etc.
}
I'd like to use Microsoft's SAL annotations from sal.h
so that the Visual Studio compiler notices when the number of parameters does not match count
. I can enforce count
as a literal this way:
int print_n_integers (
_Literal_ unsigned int count,
...
)
and Visual Studio at least has some cleverness to cope with printf()
, but is there something for simple parameter count?
I'd like to propose an alternative approach to your problem that doesn't use static analysis.
Even if you could get the count of the variadic arguments for static analysis, you'd still have to provide the correct count for each call. You'd also have to make sure that all arguments are (or can be promoted to) integers.
A more natural, non-variadic approach to handle a list of homogenouos types is to print an array:
C99 compatible compilers can create arrays on the spot with compound literals:
This syntax lends itself to be wrapped in a macro:
This macro does the counting and you can use it without explicit argument count:
The second expansion of the variadic arguments is used inside
sizeof
and not evaluated. In the line above,rand()
is called only once andi
andj
are incremented only once. The floating-point argument is converted toint
before printing.Visual Studio has introduced compound literals in 2013 RC, but older versions don't support them. Unfortunately, compound literals also render your code unusable for C++ compilers. For these cases, you could rework the macro to define a temporary array:
This strategy works only if the function is called in void context, however.
If you use only the macro, the array and its size are consistent. But you can publish the underlying implementation and annotate it with SAL:
I don't advocate the gratuitous use of macros, but in this case, the macro takes the role of a template; it can reduce dangerous redundancy.