V733. It is possible that macro expansion resulted in incorrect evaluation order.


Анализатор обнаружил потенциальную ошибку в коде, связанную с использованием макросов, раскрывающихся в арифметическое выражение. Обычно ожидается, что подвыражение, переданное как параметр в макрос будет выполняться в конечном выражении первым. Но это может быть не так, что приводит к трудно обнаруживаемым ошибкам.

Рассмотрим пример:

#define RShift(a) a >> 3
....
y = RShift(x & 0xFFF); 

Если раскрыть макрос, то мы получим:

y = x & 0xFFF >> 3;

Приоритет операции ">>" выше, чем у "&". Будет вычислено выражение "x & (0xFFF >> 3)", в то время, как программист рассчитывал получить "(x & 0xFFF) >> 3".

Для устранения недостатка требуется взять аргумент 'a' в круглые скобки:

#define RShift(a) (a) >> 3

Однако, стоит сделать ещё одно усовершенствование. Полезно взять всё выражение в макросе ещё в одни скобки. Это является хорошим тоном и может предотвратить некоторые другие ошибки. Улучшенный вариант:

#define RShift(a) ((a) >> 3)

Примечание. Родственной по смыслу диагностикой является V1003. Диагностика V1003 работает менее точно и даёт больше ложных срабатываний, так как анализирует объявление макроса, а не его использование. С другой стороны, не смотря на свои недостатки диагностика V1003 может помочь выявить ошибки, которые диагностика V733 бессильная обнаружить.

Согласно Common Weakness Enumeration, потенциальные ошибки, найденные с помощью этой диагностики, классифицируются как CWE-783.

Взгляните на примеры ошибок, обнаруженных с помощью диагностики V733.


Найденные ошибки

Проверено проектов
334
Собрано ошибок
12 668

А ты совершаешь ошибки в коде?

Проверь с помощью
PVS-Studio

Статический анализ
кода для C, C++, C#
и Java

goto PVS-Studio;