比方说,如果我使用Visual Studio 2017 C ++编译器编译以下内容:
int r = 0;
wprintf_s(L"%s", r);
它会给我这些非常方便的警告:
警告C4477:'wprintf':格式字符串'%s'需要类型为'wchar_t *'的参数,但可变参数1的类型为'int'
警告C4313:'wprintf':格式字符串中的'%s'与'int'类型的参数1冲突
但是当我尝试定义自己的可变函数时:
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注释宏。它们被静态分析工具识别,但在编译器看到之前它们被预处理器删除。所以它们在你的情况下并不是很有用。
一些第三方编译器实现了特定于供应商的方法,以便在用户定义的函数(例如GCC中的__attribute__(format)
and __attribute__(format_arg)
)上启用printf样式参数的编译时验证,但是Visual C ++不是那些编译器之一(参见__attribute__((format(printf, 1, 2))) for MSVC?)。 VC ++团队选择仅针对标准printf/scanf
系列C运行时函数启用编译时验证,如2015年博客中所述:
C++ Team Blog: Format Specifiers Checking
根据流行的请求,在Visual Studio 2015 RTM中,我们已经实现了对printf / scanf的参数检查及其在C标准库中的变化。您可以在我们的online compiler中尝试这篇文章中的示例。
...
目前,格式说明符的检查仅针对一组预定义的CRT函数进行,并且不适用于也会受益于类似检查的用户定义函数。如果有足够的兴趣,我们将考虑扩展这些警告以适用于此类用户定义的功能。
如果您真的想要对用户定义的可变参数函数进行编译时检查,请改用variadic templates。