PVS Studio 抱怨危险的宏表达式

PVS Studio complaining about dangerous macro expression

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

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

文档中也提到了这一点。 V1003 diagnostic rule operates on non-preprocessed code and the analyzer possesses no information on how this macro will be used in the future. The diagnostic rule allows to identify errors in macros which could lead to incorrect arithmetic operations. But sometimes it fails. There exists a more precise V733 诊断,但不幸的是,它可能会漏掉大量病例。

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

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

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

//-V:<<:1003

在这种情况下,使用“<<”运算符时不会触发 V1003 诊断。此注释可以放在全局头文件之一(例如 stdafx.h)或诊断配置文件 (.pvsconfig) 中。文档 Suppression of false alarms.

中提供了这些和其他抑制误报方法的详细描述