(delphi11最新学习资料)Object Pascal 手册---第1章第5节

Delphi 11 编程语言的完整介绍 作者:Marco Cantu 译者:豆豆爸

1.5 编译命令

​ 如前所述,程序结构的另一个特殊元素(除实际代码外)是编译指令。这些是编译器的特殊指令,格式如下:

{$X+}

有些编译指令只有一个字符,如上图所示,其中的加号或减号表示该指令是激活还是停用。大多数指令也有更长、更易读的版本,并使用 ON 和 OFF 来标记是否激活。有些指令只有较长的描述性格式。

​ 编译指令不会直接生成编译代码,但编译指令会影响但编译器生成代码的方式。在许多情况下,使用编译指令可以代替更改集成开发环境项目选项中的编译器设置,但在有些情况下,你只想将特定的编译器设置应用于某个单元或代码片段。

​ 我将介绍特定编译器指令,但在它们可能影响语言特性时再进行介绍。在本节中,我只想提及几个与程序代码流相关的指令:条件定义和包含。

1.5.1 条件定义

​ 条件定义指示编译器包含或忽略部分源代码。Delphi 中的条件定义有两种,一种是传统的 $IFDEF$IFNDEF,另一种是更新、更灵活的$IF

​ 这些条件定义依赖于已定义的符号,或者对于 $IF 版本来说,可以依赖于常量值。定义的符号可以由系统预定义(例如编译器和平台符号),它们可以在特定项目选项中定义,或者可以通过另一个编译器指令 $DEFINE 在代码中引入。

​ 传统的 $IFDEF$IFNDEF 的格式如下:

{$IFDEF TEST}
// 如果 TEST 被定义,这部分将被编译
{$ENDIF}

{$IFNDEF TEST}
// 如果 TEST 未被定义,这部分将不被编译
{$ENDIF}

​ 如果有多个条件,还可以使用 $ELSEIF 指令。

1.5.2 编译器版本

​ 每个版本的 Delphi 编译器都有一个特定的定义,您可以使用它来检查是否针对产品的特定版本进行编译。如果您使用的是后来推出的功能,但又想确保代码仍能在旧版本下编译,则可能需要使用该定义。

​ 如果您需要为某些较新版本的Delphi编写特定的代码,可以基于以下定义设置 $IFDEF 语句:

  • Delphi 2007 VER180
  • Delphi XE VER220
  • Delphi XE2 VER230
  • Delphi XE4 VER250
  • Delphi XE5 VER260
  • Delphi XE6 VER270
  • Delphi XE7 VER280
  • Delphi XE8 VER290
  • Delphi 10 Seattle VER300
  • Delphi 10.1 Berlin VER310
  • Delphi 10.2 Tokyo VER320
  • Delphi 10.3 Rio VER330
  • Delphi 10.4 Sydney VER340
  • Delphi 11 Alexandria VER350

​ 这些版本号的十进制数字表示编译器的实际版本(例如 Delphi XE5 中的 26)。该数字序列并非 Delphi 独有,而是可以追溯到 Borland 发布的第一个 Turbo Pascal 编译器(更多信息请参见附录 A)。

​ 您还可以在 $IF 语句中使用内部版本常量,这样做的好处是可以使用比较运算符 (>=) 而不是匹配一个特定的版本。版本常量称为 CompilerVersion,在Delphi XE5中它被分配了浮点值26.0,如下面的示例所示:

{$IF CompilerVersion >= 26)}
// 在Delphi XE5或更高版本中编译的代码
{$IFEND}

​ 同样,你也可以为你要编译的不同平台使用系统定义,以防你需要某些代码是平台相关的(在 Object Pascal 中一般是个例外情况,不是常见的做法):

Windows MSWINDOWS

macOS MACOS

iOS IOS

Android ANDROID

Linux LINUX

​ 下面是 HelloPlatform 项目的代码片段,其中包含基于上述平台定义的测试:

{$IFDEF IOS}
ShowMessage('Running on iOS上');
{$ENDIF}

{$IFDEF ANDROID}
ShowMessage('Running on Android');
{$ENDIF}
1.5.3 包含文件

​ 我想在这里介绍的另一个指令是 $INCLUDE 指令,在讨论 uses 语句时已经提到过。通过该指令,你可以在源代码文件的指定位置引用并包含源代码片段。有时,当代码片段定义了编译器指令和编译器直接使用的其他元素时,该指令可用于在不同单元中包含相同的代码片段。

​ 使用单元时,单元只被编译一次。当你包含一个文件时,该文件的代码会在被添加的每个单元中编译(这就是为什么如果同一包含文件被嵌入到同一项目的不同单元中,通常应避免在包含文件中声明任何新标识符的原因)。那么,如何使用包含文件呢?一个好的例子就是你想在大部分单元中启用的编译器指令集,或者一些额外的特殊定义。

​ 大型库经常使用包含文件来实现这一目的,FireDAC 库就是一个例子,它是一个数据库库,现已成为系统库的一部分。系统 RTL 单元展示的另一个例子是为每个平台使用单独的包含文件,并使用 $IFDEF 有条件地只包含其中一个平台。

你可能感兴趣的:(Object,Pascal,Handbook,开发语言)