портирование 32-битного на 64-битный код

0

Пробовал переносить 32-битный на 64-битный код. Мне было интересно, есть ли какие-то стандартные правила при переносе?

У меня своя компиляция кода в 64-битной среде, и теперь я сталкиваюсь с некоторыми ошибками, например

отсылать из указателя в целое число разного размера [-Werror = указатель-на-лить] для

x = (int32_t)y;

И для этого я использую x = (size_t) y; Я избавляюсь от ошибки, но это правильный путь. Кроме того, в разных местах мне нужно передать переменную в (unsigned long long). Например

printf("Total Time   : %5qu\n",time->compile_time

Это дает ошибку: format '% qu' ожидает аргумент типа long long unsigned int, но аргумент 2 имеет тип (XYZ).

чтобы получить это исправлено, я делаю что-то вроде

 printf("Total Time   : %5qu\n",(unsigned long long) time->compile_time

Опять это правильно?

  • 2
    Используйте intptr_t или uintptr_t вместо size_t .
  • 0
    Какие фактические типы x и y ?
Показать ещё 7 комментариев
Теги:
porting

2 ответа

2
Лучший ответ

Я считаю безопасным предположить, что y является указателем в этом случае.

Вместо size_t вы должны использовать intptr_t или uintptr_t.

См. Size_t vs. uintptr_t.

Что касается вашего второго броска, это зависит от того, что вы подразумеваете под правильным?

Обычный совет - избегать кастинга. Однако, как и все в программировании, есть причина, по которой они доступны. При работе над реализацией malloc во встроенной системе мне приходилось uintptr_t указатели на uintptr_t, чтобы иметь возможность выполнить необходимую арифметику. Этот код был протестирован на 64-битном ПК, но работал на 32-битном микроконтроллере. Тот факт, что я использовал две архитектуры, был лучшим способом обеспечить его портативный код.

Кастинг, хотя делает ваш код зависимым от того, как определяется базовый тип! Так же, как вы заметили с помощью x = (int32_t)y эта строка сделала ваш код зависимым от того, что указатель имел ширину 32 бит.

Единственный совет, который я могу вам дать, - это знать свои типы. Если вы хотите бросить, это нормально (до тех пор, пока вы не можете сделать свою переменную с правильным типом), но это может снизить вашу переносимость, если вы не выбрали "правильный" тип, который нужно выполнить.

То же самое относится к printf. Если бы я был вами, я сначала прочитал бы определение %5qu сначала (это может помочь). Затем я попытаюсь использовать соответствующую типизированную переменную (или, наоборот, другую строку формата), и только если это не сработало, я бы прибегнул к актерскому составу.

Я никогда не использовал %qu но я бы интерпретировал его как 64-битное беззнаковое int, поэтому я бы попытался использовать uint64_t (потому что long long не гарантировалось, что на всех платформах должно быть 64 бита). Хотя по тому, что я читал в Википедии, спецификатор q имеет специфическую платформу для начала, поэтому было бы разумно изменить его.

Не более того, и вопрос становится слишком широким (хорошо, что мы придерживались конкретных примеров). Если вы застряли, вернитесь с отдельными типами, которые вы хотите проверить и задавать вопросы только о них.

1

Было ли это, что Страуструп сказал, что они называют его "броском", потому что он воспитывает то, что сломалось? ;-)

 x = (int32_t) y;

В этом случае вы используете точный тип ширины, так что это действительно зависит от того, что такое x и y. Сообщение об ошибке предполагает, что y является указателем. Указатель не является int32_t, поэтому реальный вопрос заключается в том, почему y присваивается x... это может указывать на потенциальную проблему. Отбросить его можно просто покрыть проблему, чтобы она кусала вас во время выполнения, а не во время компиляции. Выясните, что код думает, что он делает, и "передислоцировать" типы, соответствующие этому коду. Причина, по которой ошибка уходит при использовании (size_t), заключается в том, что, вероятно, указатель имеет 64 бита, а size_t - 64 бита, но вы можете считать, что простая форма случайного каста удачи. То же самое верно при кастинге (без знака длинный). Не предполагайте, что int 32 или 64 бита и не используют литье в качестве инструмента портирования... это вызовет у вас проблемы. Трудно быть более конкретным на основе одной строки кода. Если вы хотите опубликовать функцию <25 строк, которая имеет проблемы; более конкретные рекомендации могут быть доступны.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню