我可以为我自己的可变参数函数启用有关错误使用的说明符的警告吗?

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

比如说,如果我使用 Visual Studio 2017 C++ 编译器编译以下内容:

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

它会给我这些非常方便的警告:

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'

但是当我尝试定义自己的可变参数函数时:

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

    //Do work ...

    va_end( argList );
}

然后以类似的方式调用它:

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

它不会触发它们。

所以我想知道我是否可以为我自己的可变参数函数启用这些警告?

_In_z__Printf_format_string_ 之类的东西是 SAL 注释宏。它们可以被静态分析工具识别,但在编译器看到它们之前就被预处理器删除了。所以它们在你的情况下不是很有用。

一些第 3 方编译器实现了特定于供应商的方法,以启用对用户定义函数(例如 __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?)的 printf 样式参数的编译时验证。 VC++ 团队选择仅对标准 printf/scanf 系列 C 运行时函数启用编译时验证,如他们 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.

如果您真的想对用户定义的可变参数函数进行编译时检查,请改用 variadic templates