Анализатор обнаружил потенциальную ошибку в коде, связанную с использованием макросов, раскрывающихся в арифметическое выражение. Обычно ожидается, что подвыражение, переданное как параметр в макрос будет выполняться в конечном выражении первым. Но это может быть не так, что приводит к трудно обнаруживаемым ошибкам.
Рассмотрим пример:
#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 бессильная обнаружить.
Данная диагностика классифицируется как:
|
Взгляните на примеры ошибок, обнаруженных с помощью диагностики V733. |