Что следует учитывать при написании кода, переносимого как на 32-, так и на 64-битную архитектуру

StackOverflow https://stackoverflow.com/questions/2254222

  •  20-09-2019
  •  | 
  •  

Вопрос

Какие моменты следует учитывать при написании кода, который должен быть переносимым как на 32-битные, так и на 64-битные машины?

Размышляя об этом подробнее, я считаю, что если бы вы могли поделиться своим опытом с точки зрения возникающих проблем, это помогло бы.

Добавляя к этому, однажды я столкнулся с проблемой из-за отсутствия прототипа функции, которая возвращала указатель.Когда я портировал то же самое на 64-битную машину, код давал сбой, и я долгое время понятия не имел о причине, позже понял, что предполагается, что все отсутствующие прототипы возвращают int, вызывая проблему.

Любые подобные примеры могут помочь.

РЕДАКТИРОВАТЬ:Добавление в вики сообщества.

Это было полезно?

Решение

Ошибки:

  1. Приведение указателей к целочисленным типам опасно
  2. Размеры структуры данных могут меняться
  3. Следите за расширением знака
  4. Другой ABI?

Некоторые советы и рекомендации, которые я нашел полезными:

  1. Получите целочисленный тип собственного размера (из заголовка или typedef свой собственный) и используйте его, когда у вас есть переменные, для которых размер не важен.
  2. Используйте явные типы переменных везде, где это возможно (u_int64_t, int_32_t и т. д.).

Другие советы

  • Некоторые цельные типы могут иметь разные размеры.
  • Указатели имеют разную длину.
  • Заполнение структуры
  • Выравнивание

В Windows существует только соглашение о вызовах на x64, а не на обычном компьютере x32.

Ситуация становится еще более мрачной, если у вас есть 32-битные и некоторые 64-битные компоненты.В Windows я написал COM-сервис, чтобы заставить их общаться.

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

sizeof(int) может != sizeof(void*)

выравнивание.Вполне возможно, что потребности в выравнивании могут измениться.Это может выявить ошибки, когда вы неправильно обращались с вещами, которые должны были быть выровнены, но были выровнены только случайно в 32-битной версии (или на процессоре, которому все равно).

не передавайте 0 в переменные аргументы, если получатель ожидает указатель.Это болезненно для C++, где опытные разработчики знают, что 0 — допустимый нулевой указатель.Разработчик C обычно использует NULL, так что вы, вероятно, в порядке.

Пишите автоматические тесты и регулярно запускайте их на обеих платформах.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top