# 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 бессильная обнаружить.

Данная диагностика классифицируется как:

CWE-783 CERT-PRE01-C

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