Отличия FPC от Delphi в runtime

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Ответить
Mirage
энтузиаст
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia
Контактная информация:

Отличия FPC от Delphi в runtime

Сообщение Mirage »

Итак, компилирую большой (~46K строк) проект под FPC (2.2.0) и получаю глючащую программу. Причем, если включены оптимизации, то менее глючную, чем если выключены.
Сейчас скомпилировал в релизе - нормально бегает вроде. А в дебаге вылетает.:(

Вобщем возник вопрос какие различия между D7 и FPC, проявляющиеся в runtime, кто заметил?

Я знаю про следующие:
1. Конструкции вида Boolean(I), где I - целого типа переменная, а также Byte(B), где I - булевская переменная, в общем случае не работают (да и не должны). Надо использовать Ord().
2. Процедура Move() при включенном range checking и нулевым Count вылетает с range check error (вот это уже спорно).

Какие еще есть с виду более-менее адекватные конструкции, работающие в Delphi, но не работающие в FPC?
zub
долгожитель
Сообщения: 2890
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

Мне при попытке перехода на fpc особенно запомнилась не совпадяющая с delphi последовательность инициализации юнитов при циклических uses. это я никак побороть нисмог, пришлось руками вызывать процедуры инициализации в нужных местах. ну и еще чето было по мелочи
Mirage
энтузиаст
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia
Контактная информация:

Сообщение Mirage »

Обнаружил еще одно различие в поведении.
После выполнения GetMem(p, 0) в p в Delphi nil, а в FPC что-то вроде $9CD90. Редкий случай когда поведение Delphi более адекватно.
Да что там, это в общем-то баг.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
Сообщения: 1409
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение Sergei I. Gorelkin »

Поведение GetMem соответствует не Delphi, а TurboPascal, который на запрос нуля байт памяти возвращал какой-то специальный указатель (на конец кучи, что ли?)

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

Из принципиально неисправимых вещей: по-разному работают вложенные процедуры, в Delphi такую процедуру можно использовать как callback в ф-цию WinAPI, в FPC нельзя (точнее можно, но в рантайме свалится). Фиксится путем переделки вложенной процедуры в обычную.
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

Sergei I. Gorelkin писал(а):Из принципиально неисправимых вещей: по-разному работают вложенные процедуры, в Delphi такую процедуру можно использовать как callback в ф-цию WinAPI, в FPC нельзя (точнее можно, но в рантайме свалится). Фиксится путем переделки вложенной процедуры в обычную.

А как правильно с точки зрения пролетариата, в FPC или в Delphi? :)
Mirage
энтузиаст
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia
Контактная информация:

Сообщение Mirage »

При обнаружении багов всегда качаю самую новую версию. Проверял и с 2.2.2 и 2.3.1.
А в режиме совместимости с Delphi это таки баг.
Юра
постоялец
Сообщения: 163
Зарегистрирован: 25.05.2005 10:20:09
Откуда: Украина, Киев

Сообщение Юра »

Вообще-то самый большой баг - это полагаться на результат вещей типа GetMem(p, 0).
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
Сообщения: 1409
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение Sergei I. Gorelkin »

Vadim писал(а):А как правильно с точки зрения пролетариата, в FPC или в Delphi?

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

Mirage писал(а):А в режиме совместимости с Delphi это таки баг.

Код rtl, к сожалению (или к счастью) один и тот же для всех режимов и не зависит от режима компиляции программы.
Timid
постоялец
Сообщения: 290
Зарегистрирован: 21.11.2007 20:33:15

Сообщение Timid »

Вложенная процедура, вообще-то, не должна вызываться по адресу "снаружи", поскольку она - фактическая замена "классическому" макросу в C. Код в ней может адресоваться к переменным внешней процедуры, которые разместятся в стеке только после входа в нее (внешнюю). Если же вызвать отдельно - то адресоваться придется в неизвестность. Это прямая "дыра" для DOS (хакерская атака).
Ответить