将 Turbo Pascal 移植到 Free Pascal
本文档包含有关 Free Pascal 和 Turbo Pascal 7.0(在某种程度上是 Delphi)之间差异的一些信息。此列表不完整。
更多的文档可以在 WIKI 中找到,浏览更多的 wiki 和文档。
汇编程序
- 默认的汇编程序使用另一种语法,但是你可以使用 -Rintel 命令行选项或在你的源代码中添加 {$asmmode intel} 来打开 Intel 风格汇编程序阅读器(这是 Turbo Pascal 使用的)。
- 如果你来自 TP,则 32位内存模型要求对汇编器块进行完整的重新编码。
运行时库
- 对于所有整数类型,swap(), lo() 和 hi()内在函数都是重载的,而不是始终使用16位操作数。 因此,对于32位类型,swap 将交换低16位和高16位, 类似 lo()将分别交换, hi() 也将返回低位,高16位而不是8位
- 要使用 PORT 数组,请在 use子句中添加 Ports 单元(仅在 Dos/Go32v2 和 Linux 下可用)
- 您可以使用 MEM[seg:ofs] 以及 MemW 和 MemL(仅在 Dos/Go32v2 下可用)访问真实模式内存
- Ofs() 返回 ptrint 而不是 word
- OVERLAY 单元不可用
- Free Vision 提供了 Turbo Vision 支持;一个克隆,因为原始 Turbo Vision 仍然无法免费获得(Borland 未发布版权)
预处理器/语法
- 如果使用 -So 命令行开关(或在源代码中添加 {$mode TP}),则编译器将使用其 Turbo Pascal 兼容模式,该模式将禁用 FPC 的一些高级功能(例如过程重载), 以实现与 Turbo Pascal 程序的更好兼容性。
- 允许嵌套注释,但在找到时发出警告(在 TP 模式下禁用)
语法
- FAR 和 NEAR 被忽略
- 要获取过程的地址以将其分配给过程变量,必须使用 @-operator(在 TP 和 Delphi 模式下,过程变量的工作方式与 TP 中的一样)
procedure p; begin end; var proc : procedure; begin proc:=@p; end;
语义
- 默认情况下,记录与 cpu 字的大小对齐;使用 'packed record' 或 {$PACKRECORDS 1} 获取与 TP7 兼容的记录。 提示:仅当绝对需要时才使用压缩包,因为字段的对齐可能不适用于非 Intel 处理器(在所有情况下都会减慢数据访问速度)。
type r1=record a : byte; b : word; end; r2=packed record a : byte; b : word; end; begin writeln(sizeof(r1)); { 输出 4 } writeln(sizeof(r2)); { 输出 3 } end.
function a : longint; begin a:=12; while a>4 do begin {...} end; end;
function a : longint; begin a:=12; { v---- 这里是递归调用 } if a()>4 then begin {...} end; end;
function a : longint; begin a:=12; if a>4 then exit(a*67); end;
procedure x(v : longint);forward; procedure x; { 这会重载过程 x !!!! } begin { ... } end; { 改写为: } procedure x(v : longint); begin { ... } end;
其他
- 命令行参数不同
- 并非所有编译器开关都已完全实现
- 这些单元不是二进制兼容的
- 溢出检查会影响 inc() 和 dec()
- 范围检查不仅检查数组索引的合法值,还检查在变量范围内的值。因此,如果你需要使用 {$Q-},则可能需要添加 {$R-}。
- 单元目录和引入目录的搜索顺序相反,它从最后一个目录开始。如果你有两个同名的单元,FreePascal 使用与 TurboPascal 不同的单元。
- round 函数不是以 0.5 取整,而是舍入到最近的偶数(尽管 SetRoundMode 可以控制行为)
- dos 单元 Findfirst() 调用之后必须始终跟随 Findclose 以释放某些资源。