PVS Studio жалуется на опасное выражение. Параметр ‘msg’ должен быть заключен в круглые скобки в следующем коде 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;
}
Предупреждающее сообщение от PVS Studio:
V1003 The macro 'FRED' is a dangerous expression. The parameter 'msg' must be surrounded by parentheses. sample_demo.cpp 7
Следуя предложению этого инструмента и добавив скобки:
#включают
#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 не является правильным в данном конкретном случае. Я пропустил что-то очевидное, и инструмент правильный? Спасибо заранее.
В документации также упоминается об этом. V1003 Правило диагностики работает с необработанным кодом, и анализатор не обладает информацией о том, как этот макрос будет использоваться в будущем. Правило диагностики позволяет идентифицировать ошибки в макросах, которые могут привести к неправильным арифметическим операциям. Но иногда это не удается. Там существует более точный V733 диагностика, но, к сожалению, она может пропустить большое количество случаев.
Приведенный исходный код приводит к ложному положительному результату, потому что анализатор считает, что<<‘может быть операцией смещения целочисленного значения. Если количество таких ложных срабатываний огромно, вы можете отключить диагностику V1003. Но если это единичный случай, я советую использовать ложный положительный комментарий подавления:
#define FRED(msg) (msg) << Z //-V1003
Вот альтернатива. Вы можете использовать комментарий следующим образом:
//-V:<<:1003
В этом случае диагностика V1003 не будет запущена, когда<<оператор используется. Этот комментарий может быть помещен в один из глобальных заголовочных файлов (например, stdafx.h) или в файл конфигурации диагностики (.pvsconfig). Подробное описание этих и других способов подавления ложных срабатываний доступно в документации. Подавление ложных срабатываний.
Я думаю, что это предупреждение предназначено для арифметических выражений. Например, если msg
является 0xf & 8
пропущенные скобки могут дать разные результаты, потому что operator <<
имеет более высокий приоритет, чем &
,