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的建议是不正确的。我是否错过了一些明显的东西,工具是正确的?非常感谢。
我认为此警告目标是算术表达式。例如,如果msg
是0xf & 8
省略括号可能会产生不同的结果,因为operator <<
的优先级高于&
。
文档也提到了这一点。V1003诊断规则在非预处理的代码上运行,分析仪没有有关将来如何使用该宏的信息。诊断规则允许识别宏中的错误,这可能导致算术操作不正确。但是有时候失败了。存在更精确的V733诊断,但不幸的是,它可能会错过大量病例。
引用的源代码导致误报,因为分析仪认为,"&lt;&lt;"可以是整数值转移操作。如果此类误报的数量很大,则可以禁用V1003诊断。但是,如果这是一个孤立的案例,我建议使用误报抑制评论:
#define FRED(msg) (msg) << Z //-V1003
这是另一种选择。您可以使用这样的评论:
//-V:<<:1003
在这种情况下,当'&lt;&lt;''时,V1003诊断不会触发。使用操作员。可以将此注释放在全局标头文件之一(例如stdafx.h)或诊断配置文件(.pvSconfig)中。这些抑制假阳性的这些方法的详细描述可在from from Alarms的文档抑制中可用。
相关文章:
- 既然存在危险,为什么项目要使用-I include开关
- 未初始化的变量有什么危险
- MSVC中的宏观扩展问题
- 将字符移出范围的危险
- 在C++的头文件中使用常量并在程序中询问其地址的任何潜在危险
- CRTP - 危险的内存访问?
- 危险指针的内存排序
- 在对象构造期间,将指向尚未构造的子对象的指针传递给另一个子对象的构造函数是否危险?
- 为什么 CWE 认为 rand() 具有潜在危险
- "this"关键字在C++中的实现限制,因为它与危险但功能示例有关
- cppcheck 抱怨危险地使用 c_str(). c_str() 返回的值在此调用后无效
- cpp 检查抱怨危险使用 c_str(). c_str() 返回的值在本次调用后无效,如何解决?
- C++宏观参数
- 为什么在一个地方需要双倍英镑,而在这个宏观上不需要其他地方?
- 使用危险的幻数N
- 派生类的模板类作为函数的参数 - 危险?
- CUDA:来自不同翘曲但相同块的 2 个线程尝试写入相同的共享内存位置:危险?
- 聚合初始化的 C++17 扩展是否使大括号初始化变得危险?
- 从 int 到 longlong 的危险转换:没有警告
- PVS Studio抱怨危险的宏观表达