看到一篇PVS学会在Linux下分析的刊物,决定在自己的项目上尝试一下。 这就是结果。
内容
优点
响应式支持
我请求了试用密钥,他们当天就将其发送给了我。
相当清晰的文档
我们成功地启动了分析仪,没有出现任何问题。 还提供了控制台命令的帮助(尽管这里有一些抱怨,请参阅部分
多线程分析的可能性
分析仪有一个“标准”选项 -j
,允许在多个任务中并行进行分析。 这节省了大量时间。
良好的可视化效果
许多不同的输出格式,从文本到小型网络枪口。
轻松集成到组件中
所有的文档都在他们的网站上,我只能说,如果你的项目是使用 CMake 构建的,那么一切都非常简单。
良好的诊断描述
如果您在模式下生成输出 fullhtml
,那么每条消息都有一个指向诊断描述的链接,其中包含解释、代码示例和其他链接。
缺点
分析器对 C++ 语言的无知
不幸的是,当代码完全正确时,PVS 有时会出现语法错误并生成误报消息。
例如,有一个函数返回 void
:
template <typename T>
auto copy (const void * source, void * destination)
->
std::enable_if_t
<
std::is_copy_constructible<T>::value
>
{
new (destination) T(*static_cast<const T *>(source));
}
是的,关键字 auto
可以表示 void
,这就是它的用途 汽车。 但 PVS 产生以下消息:
dynamic_tuple_management.hpp:29:1: error: V591 Non-void function should return a value.
dynamic_tuple_management.hpp:29:1: error: V2542 Function with a non-void return type should return a value from all exit paths.
网站速度非常慢
是的,在网络界面中每条消息旁边都有一个指向相应诊断描述和示例的链接。 但是当你点击一个链接时,你必须等待相当长的时间,有时会发生这种情况
选择语言
所有描述都是俄语,这很棒。 但报告中的链接始终指向英文版本。 如果能够切换语言那就太好了,这样您就可以立即用俄语查看诊断信息。 我在界面中没有找到这样的选项。
通过控制台处理诊断级别不方便
让我们从使用的两个命令(这个 pvs-studio-analyzer
и plog-converter
)用于指定诊断的不同格式。
帮助 pvs-studio-analyzer
读到:
-a [MODE], --analysis-mode [MODE]
MODE defines the type of warnings:
1 - 64-bit errors;
2 - reserved;
4 - General Analysis;
8 - Micro-optimizations;
16 - Customers Specific Requests;
32 - MISRA.
Modes can be combined by adding the values
Default: 4
我花了很长时间试图弄清楚该去哪里 添加 (“添加值”)键。 我尝试将它们列出并用逗号分隔:
pvs-studio-analyzer analyze ... -a 1,4,16
我多次尝试注册密钥:
pvs-studio-analyzer analyze ... -a 1 -a 4 -a 16
然后我才意识到这些都是位掩码! 而你需要 总结而且不 添加 含义。 例如,要获得一般诊断、微优化诊断和 MISRA,您需要将它们相加 (4 + 8 + 32 = 44):
pvs-studio-analyzer analyze ... -a 44
在用户界面中使用位掩码通常是不好的形式。 所有这些都可以在内部进行总结,并且可以为用户设置一组标志。
除此之外,还有一个实用工具 plog-converter
,它生成人类可读的静态分析信息。 她还有其他问题。
程序帮助 plog-converter
报告:
-a, --analyzer Specifies analyzer(s) and level(s) to be
used for filtering, i.e.
'GA:1,2;64:1;OP:1,2,3;CS:1;MISRA:1,2'
Default: GA:1,2
这里出现了一些以前没有的“级别”,我在文档中也没有找到有关它们的任何内容。
一般来说,还不清楚。 这就是为什么我把一切都设置为最大。
Catch 上一堆愚蠢的脏话
我分析的三个项目中有两个使用单元测试库
不考虑多线程
对于所谓不变的变量或无限循环,存在许多误报,而这些变量的工作是从不同的线程进行的,如果不是这样,那么单元测试将无法工作。
然而,静态分析器可以考虑到这一点吗? 不知道。
结果
PVS 在我的开源项目中没有发现任何真正的错误 scan-build
一般来说,所有这些分析器的印象大致相同:是的,它们捕获了一些东西,有时甚至捕获了一些重要的东西,但总的来说编译器就足够了。
我们的团队有可能使用软件开发实践来生成最少量的垃圾代码(我个人也这么认为)。 与其英勇地克服问题,不如不制造问题。
因此,我冒昧地就如何用 C++ 编写一些建议,以免射断任何人的腿或用耙子击中任何人的额头。
充分利用编译器诊断
我们的团队使用(并建议您)以下编译选项:
-Werror
-Wall
-Wextra
-Wpedantic
-Wcast-align
-Wcast-qual
-Wconversion
-Wctor-dtor-privacy
-Wenum-compare
-Wfloat-equal
-Wnon-virtual-dtor
-Wold-style-cast
-Woverloaded-virtual
-Wredundant-decls
-Wsign-conversion
-Wsign-promo
在您的项目中启用它们并了解有关您的代码的更多信息。
坚持标准
如果有标准类似物,请尽量不要使用依赖于平台的东西,如果您绝对不能没有它们,请将它们包装在宏(或其他东西)的特殊块中,并且不要让您的代码在不受支持的条件下编译。
坚持标准操作语义
加法必须是加法,乘法必须是乘法,函数调用必须是函数调用,复制必须是复制,进位必须是进位,容器必须是可迭代的,迭代器必须具有提升 ++
和解除引用 *
。 等等等等。
我认为这个想法很明确。 有些既定约定不具有约束力,但代码的所有用户和读者都希望看到这些约定。 不要试图智取别人,否则你会智取自己。
编写兼容的代码
首先,我指的是标准库。 非常希望您的类和函数的接口可以与标准库和其他库(例如,Boost)一起使用。
请随意查看 STL 和 Boost 接口。 除了极少数例外,您都会在那里看到有价值的榜样。
充分利用开源工具
对于相同的静态分析,至少有两个开放的免费工具可以使用 CMake 构建系统将它们连接到任何项目一次。
后记
最后,我想强调的是,我并不是提倡不要使用PVS或任何其他静态分析器。 但我鼓励您考虑一下静态分析器如何不断地在您的代码中发现重大错误。
这只是一个后果。 我们需要寻找并消除原因。
来源: habr.com