1

PVS Studio 抱怨一个危险的表情。在以下代码 C++ 代码中,参数“msg”必须用括号括起来

#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 的建议在这种特殊情况下是不正确的。我错过了一些明显的东西并且工具是正确的吗?提前谢谢了。

4

2 回答 2

2

我认为这个警告针对的是算术表达式。例如 if msgis0xf & 8省略括号可能会产生不同的结果,因为operator <<它的优先级高于&.

于 2017-09-28T08:38:44.117 回答
1

文档也提到了这一点。V1003诊断规则对未预处理的代码进行操作,分析器没有关于该宏将来如何使用的信息。诊断规则允许识别宏中可能导致不正确算术运算的错误。但有时它会失败。存在更精确的V733诊断,但不幸的是,它可能会漏掉大量病例。

引用的源代码导致误报,因为分析器认为'<<'可以是整数值移位操作。如果此类误报的数量很大,您可以禁用 V1003 诊断。但如果这是一个孤立的案例,我建议使用误报抑制评论:

#define FRED(msg) (msg) << Z  //-V1003

这是一个替代方案。您可以使用这样的评论:

//-V:<<:1003

在这种情况下,使用 '<<' 运算符时不会触发 V1003 诊断。此注释可以放在全局头文件之一(例如 stdafx.h)或诊断配置文件 (.pvsconfig) 中。抑制误报的这些方法和其他方法的详细描述可在文档Suppression of false alarms中找到。

于 2017-09-29T07:31:50.003 回答