﻿# V117\. Memsize type is used in the union\.


> Это правило входит в группу "Диагностика 64\\\-битных ошибок"\\\. Разработка правил этой группы больше не ведётся, и в будущем они могут быть отключены\\\. Если вы используете эти правила, \[свяжитесь с нашей поддержкой\]\(https://pvs\-studio\.ru/ru/about\-feedback/\) — мы поможем найти замену или предложим альтернативное решение\\\.

Анализатор обнаружил потенциально возможную ошибку, связанную с использованием memsize внутри объединения \(union\)\. Ошибка может возникнуть при работе с такими объединениями без учета изменения размеров memsize типов на 64\-битной системе\. 

Следует внимательно относиться к объединениям, имеющим в своем составе указатели и другие члены типа memsize\.

Первый пример\.

Иногда возникает необходимость работать с указателем, как с целым числом\. Приведенный в примере код удобен тем, что для работы с числовым представлением указателя не используются явные приведения типов\.

```cpp
union PtrNumUnion {
  char *m_p;
  unsigned m_n;
} u;
...
u.m_p = str;
u.m_n += delta;
```

'm\_n' на 64\-битной системе, мы работаем только с частью указателя 'm\_p'\. Следует использовать тип, который будет соответствовать размеру указателя, как показано ниже\.

```cpp
union PtrNumUnion {
  char *m_p;
  size_t m_n; //type fixed
} u;
```

Второй пример\.

Другое частое использование объединения заключается в представлении одного члена, набором других более мелких\. Например, нам может потребоваться разбить значение типа 'size\_t' на байты для реализации табличного алгоритма подсчета количества нулевых битов в байте\.

```cpp
union SizetToBytesUnion {
  size_t value;
  struct {
    unsigned char b0, b1, b2, b3;
  } bytes;
} u;
   
SizetToBytesUnion u;
u.value = value;
size_t zeroBitsN = TranslateTable[u.bytes.b0] +
                   TranslateTable[u.bytes.b1] +
                   TranslateTable[u.bytes.b2] +
                   TranslateTable[u.bytes.b3];
```

Здесь допущена принципиальная алгоритмическая ошибка, заключающаяся в предположении, что тип 'size\_t' состоит из 4 байт\. Возможность автоматического поиска алгоритмических ошибок на данном этапе развития статических анализаторов не возможна, но осуществляет поиск всех объединений, в которых присутствуют memsize типы\. Просмотрев список таких потенциально опасных объединений, пользователь может обнаружить логические ошибки\. Найдя приведенное в примере объединение, пользователь может обнаружить алгоритмическую ошибку и переписать код следующим образом\.

```cpp
union SizetToBytesUnion {
  size_t value;
  unsigned char bytes[sizeof(value)];
} u;
   
SizetToBytesUnion u;
u.value = value;
size_t zeroBitsN = 0;
for (size_t i = 0; i != sizeof(u.bytes); ++i)
  zeroBitsN += TranslateTable[u.bytes[i]];
```

Родственным диагностическим сообщением является [V122](https://pvs-studio.ru/ru/docs/warnings/v122/)\.

Дополнительные материалы по данной теме:

1. 64\-битные уроки\. Урок 16\. Паттерн 8\. [Memsize\-типы в объединениях](https://pvs-studio.ru/ru/blog/lessons/0016/)\.