﻿# Изменения выравнивания типов и последствия

При переносе программного обеспечения одной из забот, которая ложится на плечи разработчика является изменение размерности типов и правил их выравнивания\. Не так давно мы поддержали в анализаторе Viva64 диагностическое правило, позволяющее обнаружить структуры данных, неэффективно использующие память на 64\-битных системах\. Но в данном направлении еще стоит продолжать исследования, и я внимательно просматриваю сообщения в форумах по этому поводу\.

В этот раз мое внимание привлекло сообщение в форуме RSDN \[[1](http://rsdn.org/forum/cpp/3368697.flat)\] следующего содержания:

_Столкнулся сегодня с одной проблемой в Linux\. Есть структура данных, состоящая из нескольких полей: 64\-битный double, потом 8 unsigned char и один 32\-битный int\. Итого получается 20 байт \(8 \+ 8\*1 \+ 4\)\. Под 32\-битными системами sizeof равен 20 и всё работает нормально\. А под 64\-битным Linux'ом sizeof возвращает 24\. Т\.е\. идёт выравнивание по границе 64 бит\._

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

Когда меняются размеры полей в структуре и из\-за этого меняется сам размер структуры это понятно и привычно\. Но здесь другой случай\. Размер полей остался прежний, но из\-за иных правил выравнивания размер структуры все равно изменится\. Такое поведение может привести к разнообразным ошибкам, например в несовместимости форматов сохраняемых данных\.

Viva64 пока не поддерживает Linux системы, и я решил выяснить может ли возникнуть данный тип ошибок и в Windows системах\. Для этого я взял из статьи "C\+\+ data alignment and portability" \[[2](https://www.codesynthesis.com/~boris/blog/2009/04/06/cxx-data-alignment-portability/)\] пример кода, выводящий на печать размер типов и их выравнивание\. Немного модифицировал его для Visual Studio, после чего получилась вот такая программа:

```cpp
#include <iostream>
using namespace std;
template <typename T>
void print (char const* name)
{
  cerr << name
       << " sizeof = " << sizeof (T)
       << " alignof = " << __alignof (T)
       << endl;
}
int _tmain(int, _TCHAR *[])
{
  print<bool>        ("bool          ");
  print<wchar_t>     ("wchar_t       ");
  print<short>       ("short int     ");
  print<int>         ("int           ");
  print<long>        ("long int      ");
  print<long long>   ("long long int ");
  print<float>       ("float         ");
  print<double>      ("double        ");
  print<long double> ("long double   ");
  print<void*>       ("void*         ");
}
```

Полученные данные, я совместил с данными из статьи "C\+\+ data alignment and portability" для GNU/Linux систем и привожу их в таблице N1\.

![0009_Change_of_type_alignment_and_the_consequences_ru/image1.png](https://import.viva64.com/docx/blog/0009_Change_of_type_alignment_and_the_consequences_ru/image1.png)

Таблица N1\. Размеры типов и их выравнивание\.

Давайте изучим эту таблицу\. Обратите внимание на выделенные ячейки, относящиеся к типам long long int и double\. Эти типы не меняют свои размеры в зависимости от разрядности архитектуры\. На 32\-битной и на 64\-битных системах они имеют размер 8 байт\. Но выравнивание для 32\-битных и 64\-битных систем различно\. Это как раз и может привести к изменению размера структуры\. Когда мы будем реализовывать Viva64 под Linux\. мы обязательно учтем возможность возникновения связанных с этим потенциальных ошибок\.

В Windows системах подобных потенциальных проблем с изменением выравнивания не наблюдается\. Обратите внимание, что выравнивание всех типов остается неизменным или меняется вместе с изменением размера типа\. Хорошо\. У Windows разработчиков одной потенциальной проблемой меньше\.

Библиографический список

1. RSDN Forum\. Выравнивание на 64\-битных архитектурах\. [http://rsdn\.org/forum/cpp/3368697\.flat](http://rsdn.org/forum/cpp/3368697.flat)
1. Boris Kolpackov\. C\+\+ data alignment and portability\. [http://www\.codesynthesis\.com/\~boris/blog/2009/04/06/cxx\-data\-alignment\-portability/](https://www.codesynthesis.com/~boris/blog/2009/04/06/cxx-data-alignment-portability/)