如何在我自己的代码中使用 Visual C++ 在不运行静态代码分析的情况下导致 SAL 编译器警告
Posted
技术标签:
【中文标题】如何在我自己的代码中使用 Visual C++ 在不运行静态代码分析的情况下导致 SAL 编译器警告【英文标题】:How to cause SAL compiler warnings in my own code using Visual C++ without running static code analysis 【发布时间】:2021-06-17 00:14:00 【问题描述】:如果我在 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 的原始编译器警告之外,它还会为我提供 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 *'
...
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]'.
但我的问题是:是否有可能在不求助于运行代码分析的情况下为my_printf
获得与printf
相同的编译器警告?
不能为我正在进行的大型项目启用代码分析。
【问题讨论】:
SAL 注释对编译器没有影响,它们只是空宏。它们只影响分析工具 但不知何故,它们确实对 printf 产生了影响。 不,实际上他们没有。编译器仅具有特定于printf
的内置知识(以及其他类似的标准函数),因此可以在编译时验证其输入,仅此而已。那是一个编译器扩展。例如,gcc 在函数声明中通过__attribute__((format(...)))
提供了类似的特性,但 MSVC 不支持用户定义函数的该特性,仅支持 SAL 注释。
真可惜。我找到了另一个答案,再次证实了你所说的:***.com/questions/2354784/…
@kaylum 这个问题同样适用于 C 和 C++,即使示例代码是 C++,所以我认为不需要删除 C 标记。
【参考方案1】:
SAL 注释在编译阶段没有任何作用,因为它们被实现为空的预处理器宏。它们只对静态分析工具有影响。
对于printf()
(和其他类似的标准函数,如scanf()
),现代编译器对其参数的要求具有内置知识,因此可以在编译时验证用户提供的参数值.但这是一个编译器扩展,不是由 C/C++ 标准定义的。
例如,gcc 和 clang 通过使用__attribute__((format(...)))
装饰一个printf
风格的用户函数来提供编译时验证,但MSVC does not support that feature 目前只支持SAL 注释。
【讨论】:
以上是关于如何在我自己的代码中使用 Visual C++ 在不运行静态代码分析的情况下导致 SAL 编译器警告的主要内容,如果未能解决你的问题,请参考以下文章
Visual Studio 2013 - 如何在我自己的库中链接/包含其他库
如何在 Microsoft Visual C++ Express 中运行 C++ 简单代码 [关闭]
如何在 C++ 中使用 Microsoft Visual Studio 2012 查找语法错误?
如何在 Visual C++ 中制作 dll,我想用 C# 进行交互