1

If I create a new console project in VS 2019 and add my own annotated implementation of printf and call both real printf and my version:

    // SALTest.cpp : This file contains the 'main' function. Program execution begins and ends there.
    //

    #include <iostream>
    #include <cstdarg>

    int my_printf(_In_z_ _Printf_format_string_ char const* const format, ...)
    {
        va_list arglist;
        va_start(arglist, format);
        int result = _vfprintf_l(stdout, format, nullptr, arglist);
        va_end(arglist);
        return result;
    }

    int main()
    {
        printf("Hello World!\n");

        printf("printf good: %s\n", "narrow string");
        printf("printf bad: %s\n", L"wide string");
        my_printf("my_printf good: %s\n", "narrow string");
        my_printf("my_printf bad: %s\n", L"wide string");
    }

When I compile the file I see a compiler warning for the misuse of printf but not for the misuse of my_printf:

1>------ Build started: Project: SALTest, Configuration: Debug Win32 ------
1>SALTest.cpp
1>C:\Code\SALTest\SALTest.cpp(21,12): warning C4477: 'printf' : format string '%s' requires an argument of type 'char *', but variadic argument 1 has type 'const wchar_t *'

Now it is true that I can "Run Code Analysis on File (Ctrl+Shift+Alt+F7)" and that will give me code analysis warnings for both printf and my_printf in addition to the original compiler warning for printf:

1>------ Build started: Project: SALTest, Configuration: Debug Win32 ------
1>SALTest.cpp
1>C:\Code\SALTest\SALTest.cpp(21,12): warning C4477: 'printf' : format string '%s' requires an argument of type 'char *', but variadic argument 1 has type 'const wchar_t *'
...
C:\Code\SALTest\SALTest.cpp(21): warning C6303: Format string mismatch:  wide character string passed as _Param_(2) when character string is required in call to 'printf' Actual type: 'const wchar_t [12]'.
C:\Code\SALTest\SALTest.cpp(23): warning C6303: Format string mismatch:  wide character string passed as _Param_(2) when character string is required in call to 'my_printf' Actual type: 'const wchar_t [12]'.

But my question is this: is it possible to get the same compiler warning for my_printf that I get for printf without resorting to running a code-analysis? Turning on code-analysis for the huge project I'm on is not an option.

4

1 回答 1

3

SAL 注释在编译阶段没有任何作用,因为它们被实现为空的预处理器宏。它们只对静态分析工具有影响。

printf()(以及其他类似的标准函数,如scanf())的情况下,现代编译器具有对其参数要求的内置知识,因此可以在编译时验证用户提供的参数值。但这是一个编译器扩展,不是由 C/C++ 标准定义的。

例如,gcc 和 clangprintf通过用 装饰它来提供 -style 用户函数的编译时验证__attribute__((format(...))),但MSVC 目前不支持该功能,它只支持 SAL 注释。

于 2021-06-17T00:49:56.983 回答