说,如果我使用Visual Studio 2017 C 编译器编译以下内容:
int r = 0;
wprintf_s(L"%s", r);
它将给我这些非常方便的警告:
警告C4477:'wprintf':格式字符串'%s'需要一个论点 类型'WCHAR_T *',但是Variadic参数1具有'int'
警告 C4313:'wprintf':格式字符串中的'%s'与参数1的冲突 键入'int'
但是,当我尝试定义自己的variadic函数时:
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注释宏。它们是通过静态分析工具认可的,但是在编译器看到它们之前,预处理器将它们删除。因此,它们在您的情况下不是很有用。
某些第三方编译器实现了供应商特定的方法来启用用户定义功能上的printf式参数的编译时间验证(例如,GCC中的__attribute__(format)
和__attribute__(format_arg)
),但是Visual C 不是这些编译器之一(请参阅__ Attribute__ __attribute__((格式(printf,1,2)))用于MSVC?)。VC 团队选择仅针对标准C_5 C运行时功能的标准printf/scanf
家族启用编译时间验证,如2015年的博客:
C 团队博客:格式指定器检查
通过流行请求,在Visual Studio 2015 RTM中,我们已经实施了对printf/scanf给出的参数及其在C标准库中的变化的检查。您可以在我们的在线编译器中尝试此帖子中的示例。
...
当前,格式指定器的检查仅针对预定义的CRT功能进行,并且不适合用户定义的功能,这些功能也将从类似的检查中受益。如果有足够的兴趣,我们将考虑将这些警告扩展到此类用户定义的功能。
如果您确实需要对用户定义的variadic函数进行编译时检查,请改用variadic模板。