Search code examples
c++visual-studio-2017variadic-functionsvariadic

Can I enable warnings about incorrectly used specifiers for my own variadic function?


Say, if I compile the following using Visual Studio 2017 C++ compiler:

int r = 0;
wprintf_s(L"%s", r);

It will give me these very handy warnings:

warning C4477: 'wprintf' : format string '%s' requires an argument of type 'wchar_t *', but variadic argument 1 has type 'int'

warning C4313: 'wprintf': '%s' in format string conflicts with argument 1 of type 'int'

But when I try to define my own variadic function:

void MyFormat(_In_z_ _Printf_format_string_ LPCTSTR pszFormat, ...)
{
    va_list argList;
    va_start( argList, pszFormat );

    //Do work ...

    va_end( argList );
}

and then call it in a similar manner:

int r = 0;
MyFormat(L"%s", r);

It doesn't trigger them.

So I'm wondering if I can enable those warnings for my own variadic function?


Solution

  • Things like _In_z_ and _Printf_format_string_ are SAL annotation macros. They are recognized by static analysis tools, but they are removed by the preprocessor before the compiler ever sees them. So they are not very useful in your situation.

    Some 3rd party compilers implement vendor-specific ways to enable compile-time validation of printf-style parameters on user-defined functions (such as __attribute__(format) and __attribute__(format_arg) in GCC), however Visual C++ is not one of those compilers (see __attribute__((format(printf, 1, 2))) for MSVC?). The VC++ team chose to enable compile-time validations for only the standard printf/scanf family of C runtime functions, as documented on their blog in 2015:

    C++ Team Blog: Format Specifiers Checking

    By popular request, in Visual Studio 2015 RTM, we’ve implemented the checking of arguments given to printf/scanf and their variations in the C standard library. You can try the examples from this post in our online compiler.

    ...

    Currently, the checking of format specifiers is only done for a predefined set of CRT functions and is not available for user-defined functions that would also benefit from similar checks. If there is enough interest, we will consider extending these warnings to work on such user-defined functions.

    If you really want compile-time checking of user-defined variadic functions, use variadic templates instead.