Возможный дубликат:
Как подготовиться к 64-битам при переходе на Delphi 2010 и Unicode
Поскольку я считаю, что компилятор Delphi 64 бит появится в ближайшее время, Мне любопытно, если кто-нибудь знает, какие программы которые теперь 32bit будут компилироваться и работать без каких-либо изменений при использовании 64-битного компилятора.
И если есть общее правило, какие изменения должны мы систематически делать в наших старых программах для компиляции как 64bit?
Хорошо быть готовым, когда компилятор 64bit будет внезапно здесь...
Любое предложение будет высоко оценено.
Прежде всего, отказ от ответственности: хотя я работаю на Embarcadero. Я не могу говорить за своего работодателя. То, что я собираюсь написать, основано на моем собственном мнении о том, как должна работать гипотетическая 64-разрядная Delphi, но могут быть или не быть конкурирующие мнения и другие предусмотренные или непредвиденные несовместимости и события, которые вызывают альтернативные дизайнерские решения.
Это сказало:
Существует два целочисленных типа: NativeInt и NativeUInt, размер которых будет плавать между 32-битными и 64-битными в зависимости от платформы. Они были вокруг довольно много выпусков. Никакие другие целочисленные типы не изменят размер в зависимости от битности цели.
Убедитесь, что в любом месте, которое полагается на значение указателя, integer или наоборот использует NativeInt или NativeUInt для целого числа тип. TComponent.Tag должен быть NativeInt в более поздних версиях Delphi.
Я бы предложил не использовать NativeInt или NativeUInt для значений, не содержащих указателей. Постарайтесь, чтобы ваш код семантически совпал между 32-битным и 64-битным. Если вам нужно 32 бита диапазона, используйте Integer; если вам нужны 64 бита, используйте Int64. Таким образом, ваш код должен работать одинаково на обеих битах. Только если вы используете значение типа указателя какого-либо типа, например ссылку или THandle, следует использовать NativeInt.
Используйте PByte
для арифметики указателя, где это возможно, вместо NativeInt
или NativeUInt
. Этого достаточно для большинства целей и более типично, потому что его нельзя (легко) ошибочно принять за обычный целочисленный тип и наоборот.
Пойнтер-подобные вещи должны следовать аналогичным правилам указателям: объект (очевидно), но также такие вещи, как HWND, THandle и т.д.
Не полагайтесь на внутренние детали строк и динамических массивов, например их данные заголовка.
Наша общая политика по изменениям API для 64-разрядной версии должна состоять в том, чтобы сохранить один и тот же API между 32-битными и 64-битными, если это возможно, даже если это означает, что 64-битный API не обязательно использует машину. Для Например, TList, вероятно, будет обрабатывать MaxInt div SizeOf (Pointer) элементов, чтобы сохранить Count, индексы и т.д. как Integer. Поскольку Тип Integer не будет плавать (т.е. Изменить размер в зависимости от битности), мы не хотят иметь волновой эффект на код клиента: любые индексы, которые round-tripped через переменную типа Integer или индекс for-loop, будет усекаться и потенциально вызвать тонкие ошибки.
Если API-интерфейсы расширены для 64-разрядных, они, скорее всего, будут выполнены с помощью дополнительную функцию/метод/свойство для доступа к дополнительным данным, и это API также будет поддерживаться в 32-разрядной версии. Например, стандарт Length() процедура, вероятно, вернет значения типа Integer для аргументов тип строки или динамический массив; если кто-то хочет иметь дело с очень большими динамических массивов, может быть и процедура LongLength(), чья реализация в 32-бит такая же, как Length(). Длина() будет бросать исключение в 64-битном случае применяется к динамическому массиву с более чем 2 ^ 32 элементы.
В связи с этим, вероятно, будет улучшена проверка ошибок для сужение операций на языке, особенно сужение 64-битных значений до 32-разрядных местоположений. Это повлияло бы на удобство назначения возвращаемое значение Length для местоположений типа Integer, если Length(), вернулся Int64. С другой стороны, специально для компилятора-магии функции, такие как Length(), может быть какое-то преимущество магии, например, переключите тип возврата на основе контекста. Но преимущество не может быть аналогично взяты в не магических API.
Динамические массивы, вероятно, поддерживают 64-битную индексацию. Обратите внимание, что Java массивы ограничены 32-разрядной индексацией даже на 64-битных платформах.
Строки, вероятно, будут ограничены 32-разрядной индексацией. У нас есть время придумывает реалистичные причины для людей, желающих 4GB + строки это действительно строки, а не только управляемые капли данных, для которых динамические массивы могут также служить.
Возможно, встроенный ассемблер, но с ограничениями, например, неспособный свободно смешивать с кодом Delphi; существуют также правила вокруг исключений и макета фрейма стека, которые должны соблюдаться на x64.
Прежде всего, FreePascal уже предлагает поддержку 64-битных. Однако это не Delphi.
Во-вторых, я ожидаю, что те же проблемы, которые существовали в то время, когда Delphi 1 был обновлен до Delphi 2. Самая большая проблема заключается в основном в адресном пространстве, и проблема в том, что указатели будет увеличена с 4 до 8 байтов. В WIN16 они используются как 2 байта, и для достижения границы 64 КБ необходим трюк, используя сегменты и смещения для указателей. (С возможностью использования сегментов по умолчанию для нескольких задач.)
Вероятно также, что некоторые типы данных станут больше, чем сейчас. Скорее всего, будет целочисленный тип 8 байтов. (В Windows 2 используется только 2 байта). Перечисления, скорее всего, тоже станут больше. Но большинство других типов данных, скорее всего, сохранят свой текущий размер, поэтому здесь не так уж много изменений.
Еще одна проблема - требования к памяти. Поскольку указатели будут иметь длину 8 байтов, приложение, использующее многие из них, также будет потреблять намного больше памяти. Список с 10.000 указателями будет увеличен с 40.000 байт до 80.000 байт. Возможно, вы захотите использовать немного больше памяти, чем в 32-битной системе.
Скорость также немного изменится. Поскольку процессор теперь обрабатывает 8 байтов одновременно, он может обрабатывать данные намного быстрее. Но поскольку указатели и некоторые типы данных становятся больше, прием или отправка их на какое-либо устройство или память будет немного медленнее. В общем, ваши приложения в целом будут немного быстрее, но некоторые части могут стать медленнее!
Наконец, изменения в Windows API потребуют от вас использовать 64-битные функции API. Может быть, компилятор Delphi сделает что-то умное, чтобы позволить коду вызывать 32-битные функции API, но это снизит производительность, потому что теперь процессор переключается между собственным 64-битным режимом и эмулированным 32-битным режимом.
Было задано много похожих вопросов, когда было объявлено, что Delphi 2009 будет создавать только приложения Unicode. В конце концов выяснилось, что самый существующий код работает нормально, без изменений. Трудные части были кодом, который предполагал, что SizeOf(Char) = 1
и сторонние компоненты, которые могут это делать.
Я бы ожидал, что переход на 64-битный Delphi будет аналогичным. Все просто работает вне коробки, за исключением кода, который играет трюки с указателями и предполагает, что SizeOf(Pointer) = 4
или SizeOf(Pointer) = SizeOf(Integer)
. Вы уже можете исправить такие проблемы сегодня, вызвав SizeOf(Pointer)
, а не hardcoding 4
и используя NativeInt
или NativeUInt
, когда вам нужны целые числа с размером указателя.
Вы должны использовать SizeOf(Pointer)
, а не SizeOf(NativeInt)
, если вы хотите, чтобы ваш код работал с Delphi 2007. Delphi 2007 имеет неудачную ошибку, которая заставляет SizeOf(NativeInt)
возвращать 8 вместо 4, как следует. Это было исправлено в Delphi 2009.
В зависимости от вашего кода вы можете попытаться скомпилировать его с помощью FreePascal, который поддерживает как 32-битную, так и 64-битную компиляцию. Компилятор предупредит вас о возможно ошибочных местах вашего кода.
Подавляющее большинство простых приложений должно работать нормально. Насколько я вижу, только приложения, которые вручную используют указатели, подвергаются риску. Действительно, если указатель теперь является 64-битным, и вы используете его в вычислениях вместе с целыми числами или кардиналами (которые по умолчанию по-прежнему 32-битные), у вас возникнут проблемы. Я также считаю довольно распространенным, что декларации для функций API, которые принимают указатели в качестве аргументов, используют cardinal
вместо (целочисленного) типа (без знака).
Чтобы сделать код, который хорошо работает на любой платформе, следует использовать NativeUInt
(IIRC, теперь у меня нет компилятора Deplhi) вместо cardinal
при работе с указателями и целыми числами.
Tag
может стать 64-битным? Я предполагаю, что это не сломает любой существующий код, хотя ...
Пока Embarcadero не публикует официальную информацию об их 64-битной реализации, нелегко сказать. Вы должны проверять любые нажатия на/из указателя, Integer и Cardinal, предполагая, что они являются собственными размерами платформы, включая свойства объекта и ссылки (например, сохранение Integer в свойстве TObject, которое является указателем, или использование тега для хранения ссылок, а не цифр).
Вы также должны убедиться, что никакой код не использует эффект "обтекания" при увеличении (или уменьшении) значения в максимальном (минимальном) размере.
Проверьте любой код в структурах, которые зависят от размера данных, и не используют SizeOf() правильно, и в целом, что SizeOf() всегда используется, когда имеет значение data. Проверьте код, который записывает/читает данные в файлы, если размеры могут меняться, особенно если данные необходимо обменять между 32 и 64-битным кодом.
Проверьте изменения Win64, если приложение вызывает API и управляет сообщениями Windows напрямую. Кодированный код ASM должен быть проверен на совместимость с 64 бит (существует гораздо более строгий правило для написания 64-битного ассемблера).
Помимо очевидных задач указателя ↔ int: (используя intptr/nativeint/ptrint и т.д.)
Укладка проблемы с записями - это то, что я заметил при переносе существующих заголовков на win64.
Мои 2 цента:
в старые времена каждый автор asm должен был нажать ИСПОЛЬЗОВАТЬ BASM
внешний asm64 был бы приемлемым, а использование старого кода inlclude xy.obj, в любом случае требуется полная переписывание
Отладчик и CPU64: вопрос будет в том, что это еще есть?
D64 Float Extended: поддерживается ли это как 80-битный float?
Нр
Как полная догадка, любой код, который не зависит от определенного размера слова, или может адаптировать его размер слова на основе того, что говорит компилятор, будет в порядке.