如何在没有 运行 静态代码分析的情况下使用 Visual C++ 在我自己的代码中引起 SAL 编译器警告

How to cause SAL compiler warnings in my own code using Visual C++ without running static code analysis

如果我在 VS 2019 中创建一个新的控制台项目并添加我自己的 printf 注释实现并同时调用真实 printf 和我的版本:

    // 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");
    }

当我编译文件时,我看到编译器警告误用 printf 而不是误用 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 *'

现在我确实可以“运行 文件代码分析 (Ctrl+Shift+Alt+F7)”,这会给我 printf 和 my_printf 的代码分析警告除了 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]'.

但我的问题是:是否可以在不求助于 运行 代码分析的情况下获得与 printf 相同的 my_printf 编译器警告? 为我正在进行的大型项目打开代码分析不是一个选项。

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

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

例如,gcc 和 clang 通过用 __attribute__((format(...))) 修饰来提供对 printf 风格的用户函数的编译时验证,但目前 MSVC does not support that feature 仅支持SAL 注释。