﻿# V2644\. MISRA\. Controlling expression of generic selection must not have side effects\.

Диагностическое правило основано на руководстве [MISRA](https://misra.org.uk/) \(Motor Industry Software Reliability Association\) по разработке программного обеспечения\.

Правило актуально только для языка C\.

Управляющее выражение конструкции [\_Generic](https://en.cppreference.com/w/c/language/generic.html) \(C11\) не должно содержать каких\-либо побочных эффектов, если выражение общего выбора не было получено через раскрытие макроса\.

Такое ограничение обусловлено тем, что управляющее выражение [никогда не вычисляется](https://en.cppreference.com/w/c/language/generic.html#Notes) и, следовательно, любые побочные эффекты в нём не изменяют состояние программы\.

К побочным эффектам относятся:

1. Модификация любой переменной \(любой инкремент/декремент, присваивание\);
1. Вызов любой функции\.

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

```cpp
#if SOME_CONDITION
#define DATA_TYPE int
#else
#define DATA_TYPE unsigned
#endif // SOME_CONDITION

typedef struct CustomType
{
  DATA_TYPE data;
} *const CustomCPTR;

void InitializeData(const void *ptr)
{
  CustomCPTR customData = (CustomCPTR)(ptr);

  _Bool isOk = (_Generic(customData->data = 0
               , unsigned int : 1
               , default: 0));

  if (!isOk) return;
  // Do something
}
```

В коде приведена функция, которая должна каким\-то образом инициализировать поле структуры\. В начале делается проверка, что поле класса имеет подходящий тип\. Вместе с этой проверкой выполняется инициализация поля `data`\. Ожидалось, что при любом сценарии поле `data` будет инициализировано нулём\. Однако инициализация не произойдёт, т\.к\. выражение `customData->data = 0` находится в невычислимом контексте\.

Исправить это можно так:

```cpp
void InitializeData(const void *ptr) {
  CustomCPTR customData = (CustomCPTR)(ptr);
  customData->data = 0;

  _Bool isOk = (_Generic(customData->data
               , unsigned int : 1
               , default: 0));
  if (!isOk) return;
  // Do something
}
```