PVS Studio жалуется на опасное выражение макроса

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 не является правильным в данном конкретном случае. Я пропустил что-то очевидное, и инструмент правильный? Спасибо заранее.

1

Решение

В документации также упоминается об этом. V1003 Правило диагностики работает с необработанным кодом, и анализатор не обладает информацией о том, как этот макрос будет использоваться в будущем. Правило диагностики позволяет идентифицировать ошибки в макросах, которые могут привести к неправильным арифметическим операциям. Но иногда это не удается. Там существует более точный V733 диагностика, но, к сожалению, она может пропустить большое количество случаев.

Приведенный исходный код приводит к ложному положительному результату, потому что анализатор считает, что<<‘может быть операцией смещения целочисленного значения. Если количество таких ложных срабатываний огромно, вы можете отключить диагностику V1003. Но если это единичный случай, я советую использовать ложный положительный комментарий подавления:

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

Вот альтернатива. Вы можете использовать комментарий следующим образом:

//-V:<<:1003

В этом случае диагностика V1003 не будет запущена, когда<<оператор используется. Этот комментарий может быть помещен в один из глобальных заголовочных файлов (например, stdafx.h) или в файл конфигурации диагностики (.pvsconfig). Подробное описание этих и других способов подавления ложных срабатываний доступно в документации. Подавление ложных срабатываний.

1

Другие решения

Я думаю, что это предупреждение предназначено для арифметических выражений. Например, если msg является 0xf & 8 пропущенные скобки могут дать разные результаты, потому что operator << имеет более высокий приоритет, чем &,

2

По вопросам рекламы [email protected]