Для получения триального ключа
заполните форму ниже
Team License (базовая версия)
Enterprise License (расширенная версия)
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Бесплатная лицензия PVS-Studio для специалистов Microsoft MVP
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Для получения лицензии для вашего открытого
проекта заполните, пожалуйста, эту форму
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Мне интересно попробовать плагин на:
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте папку
Spam/Junk и нажмите на письме кнопку "Не спам".
Так Вы не пропустите ответы от нашей команды.

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

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

29 Апр 2009

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

В этот раз мое внимание привлекло сообщение в форуме RSDN [1] следующего содержания:

Столкнулся сегодня с одной проблемой в 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] пример кода, выводящий на печать размер типов и их выравнивание. Немного модифицировал его для Visual Studio, после чего получилась вот такая программа:

#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

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

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

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

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

Популярные статьи по теме
Как обнаружить переполнение 32-битных переменных в длинных циклах в 64-битной программе?

Дата: 22 Мар 2016

Автор: Андрей Карпов

Одна из проблем, с которой сталкиваются разработчики 64-битных приложений, это переполнение 32-битных переменных в очень длинных циклах. С этой задачей хорошо справляется анализатор кода PVS-Studio (…
C++11 и 64-битные ошибки

Дата: 29 Апр 2014

Автор: Андрей Карпов

64-битные компьютеры давно и успешно используются. Большинство приложений стали 64-битными. Это позволяет им использовать больший объем памяти, а также получить прирост производительности за счёт арх…
Коллекция примеров 64-битных ошибок в реальных программах

Дата: 29 Июн 2010

Автор: Андрей Карпов

Статья представляет собой наиболее полную коллекцию примеров 64-битных ошибок на языках Си и Си++. Статья ориентирована на разработчиков Windows-приложений, использующих Visual C++, но будет полезна …

Комментарии (0)

Следующие комментарии
Этот сайт использует куки и другие технологии, чтобы предоставить вам более персонализированный опыт. Продолжая просмотр страниц нашего веб-сайта, вы принимаете условия использования этих файлов. Если вы не хотите, чтобы ваши данные обрабатывались, пожалуйста, покиньте данный сайт. Подробнее →
Принять