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

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

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

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

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

y \= x & 0xFFF \>\> 3;

[Приоритет операции](https://pvs-studio.ru/ru/blog/terms/0064/) "\>\>" выше, чем у "&"\. Будет вычислено выражение "x & \(0xFFF \>\> 3\)", в то время, как программист рассчитывал получить "\(x & 0xFFF\) \>\> 3"\.

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

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

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

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

**Примечание\.** Родственной по смыслу диагностикой является [V1003](https://pvs-studio.ru/ru/docs/warnings/v1003/)\. Диагностика V1003 работает менее точно и даёт больше ложных срабатываний, так как анализирует объявление макроса, а не его использование\. С другой стороны, не смотря на свои недостатки диагностика V1003 может помочь выявить ошибки, которые диагностика V733 бессильная обнаружить\.