PVS Studio complains about a dangerous expression. The parameter 'msg' must be surrounded by parentheses on following code C++ code
#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;
}
The warning message from PVS Studio is
V1003 The macro 'FRED' is a dangerous expression. The parameter 'msg' must be surrounded by parentheses. sample_demo.cpp 7
Following the suggestion from this tool and adding parentheses: #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;
}
This change seem to create invalid code. The compiler error from VS2017 is as follows:
error C2296: '<<': illegal, left operand has type 'const char [2]'
error C2297 : '<<' : illegal, right operand has type 'const char [7]'
Question
I am pretty sure the suggestion from PVS Studio is not correct in this particular case. Did i miss something obvious and the tool is correct? Many thanks in advance.
The documentation also mentions this. The 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 diagnostic, but, unfortunately, it could miss a large number of cases.
The quoted source code leads to the false positive, because the analyzer thinks, that the '<<' can be the integer value shift operation. If the number of such false positives is huge, you can disable the V1003 diagnostic. But if this is an isolated case, I advise to use the false positive suppression comment:
#define FRED(msg) (msg) << Z //-V1003
Here is an alternative. You can use the comment like this:
//-V:<<:1003
In this case, the V1003 diagnostic will not be triggered when the '<<' operator is used. This comment could be placed in one of the global header files (for example, the stdafx.h) or in the diagnostic configuration file (.pvsconfig). The detailed description of these and other ways of suppressing false positives is available in the documentation Suppression of false alarms.