PVS Studio抱怨表达危险。参数'msg'必须用以下代码C ++代码
上的括号括起来#include <iostream>
#define X ("X")
#define Y ("Y")
#define Z ("Z")
#define FRED(msg) msg << Z // <<-- Warning from PVS Studio
#define WILMA(msg) X << FRED(msg)
#define BUDDY(msg) Y << FRED(msg)
int main()
{
std::cout << WILMA(BUDDY("xxxxxx")) << std::endl;
return 0;
}
来自PVS Studio的警告消息
V1003 The macro 'FRED' is a dangerous expression. The parameter 'msg' must be surrounded by parentheses. sample_demo.cpp 7
按照此工具的建议并添加括号: #include
#define X ("X")
#define Y ("Y")
#define Z ("Z")
#define FRED(msg) (msg) << Z
#define WILMA(msg) X << FRED(msg)
#define BUDDY(msg) Y << FRED(msg)
int main()
{
std::cout << WILMA(BUDDY("xxxxxx")) << std::endl;
return 0;
}
此更改似乎会创建无效代码。 VS2017的编译错误如下:
error C2296: '<<': illegal, left operand has type 'const char [2]'
error C2297 : '<<' : illegal, right operand has type 'const char [7]'
问题
我非常确定PVS Studio的建议在这种特殊情况下是不正确的。我错过了一些明显的东西并且工具是否正确?非常感谢提前。
答案 0 :(得分:2)
我认为这个警告针对的是算术表达式。例如,如果msg
为0xf & 8
,则省略括号可能会产生不同的结果,因为operator <<
的优先级高于&
。
答案 1 :(得分:1)
文档也提到了这一点。 V1003诊断规则对非预处理代码进行操作,分析器不具备将来如何使用此宏的信息。诊断规则允许识别宏中的错误,这可能导致不正确的算术运算。但有时它会失败。存在更精确的V733诊断,但不幸的是,它可能会遗漏大量病例。
引用的源代码导致误报,因为分析师认为,&#39;&lt;&lt;&lt;可以是整数值移位操作。如果此类误报的数量很大,您可以禁用V1003诊断。但如果这是一个孤立的案例,我建议使用误报抑制评论:
#define FRED(msg) (msg) << Z //-V1003
这是另一种选择。你可以使用这样的评论:
//-V:<<:1003
在这种情况下,当&#39;&lt;&lt;&lt;&lt;&lt;&#使用运算符。此注释可以放在一个全局头文件(例如,stdafx.h)或诊断配置文件(.pvsconfig)中。有关这些以及其他抑制误报的方法的详细说明,请参阅文档Suppression of false alarms。