Conditional compilation (Delphi)

From RAD Studio
Jump to: navigation, search

Go Up to Delphi Compiler Directives (List) Index

Conditional compilation is based on the existence and evaluation of constants, the status of compiler switches, and the definition of conditional symbols.

Conditional symbols work like Boolean variables: they are either defined (True) or undefined (False). Any valid conditional symbol is treated as false until it has been defined.

You can define a conditional in the following ways:

  • Use the {$DEFINE} directive to set a specified symbol to True, and the {$UNDEF} directive to set the symbol to False.
  • Use the -D switch with the command-line compiler (this option is supported by all the Delphi compilers).
  • Add the symbol to the Conditional Defines field on the Project > Options > Delphi Compiler page.

The conditional directives {$IFDEF}, {$IFNDEF}, {$IF}, {$ELSEIF}, {$ELSE}, {$ENDIF}, and {$IFEND} allow you to compile or suppress code based on the status of a conditional symbol. {$IF} and {$ELSEIF} allow you to base conditional compilation on declared Delphi identifiers. {$IFOPT} compiles or suppresses code depending on whether a specified compiler switch is enabled.

For example, the following Delphi code snippet processes differently depending on whether the DEBUG conditional define is set ({$DEFINE DEBUG}):

  {$DEFINE DEBUG}
    {$IFDEF DEBUG}
    Writeln('Debug is on.');  // This code executes.
    {$ELSE}
    Writeln('Debug is off.');  // This code does not execute.
    {$ENDIF}
    {$UNDEF DEBUG}
    {$IFNDEF DEBUG}
    Writeln('Debug is off.');  // This code executes.
    {$ENDIF}

Note: Conditional symbols are not Delphi identifiers and cannot be referenced in actual program code. Similarly, Delphi identifiers cannot be referenced in any conditional directives other than {$IF} and {$ELSEIF}.

Note: Conditional definitions are evaluated only when source code is recompiled. If you change a conditional symbol status and then rebuild a project, source code in unchanged units may not be recompiled. Use Project > Build All Projects to ensure that everything in your project reflects the current status of conditional symbols.

Note: If you modify the name of a conditional define in the Project > Options > Delphi Compiler, you need to Build your project (Project > Build <ProjectName> or Shift + F9) for the changes to take effect.

Conditional-directive constructions can be nested up to 32 levels deep. For every {$IFxxx}, the corresponding {$ENDIF} or {$IFEND} must be found within the same source file. Conditional symbols must start with a letter, followed by any combination of letters, digits, and underscores; they can be of any length, but only the first 255 characters are significant.

Predefined Conditionals

The following standard conditional symbols are defined:

Category Symbol DCC32   DCC64  
  Since XE2  
  DCCOSX  
  Since XE2  
  DCCIOSARM  
  Since XE3  
  DCCIOS32  
  Since XE3  
  DCCAARM  
In XE5
  DCCIOSARM64  
  Since XE8  
Comments
Compiler DCC DEFINED DEFINED DEFINED DEFINED DEFINED DEFINED DEFINED
VER310

For a list of compiler versions, see Compiler Versions.
DEFINED DEFINED DEFINED DEFINED DEFINED DEFINED DEFINED For Delphi Berlin, compiler version 31.0 has VER310 defined.
Platform CONSOLE DEFINED DEFINED DEFINED DEFINED DEFINED DEFINED DEFINED Defined if an application is being compiled as a console application.
IOS not defined not defined not defined DEFINED DEFINED N/A DEFINED Defined if the target platform is iOS.
*New* in XE4/iOS
IOS32 not defined not defined not defined DEFINED DEFINED not defined not defined Defined if the target platform is iOS32.
Since XE8/iOSarm64
IOS64 not defined not defined not defined not defined not defined not defined DEFINED Defined if the target platform is iOS64.
Since XE8/iOSarm64
NATIVECODE DEFINED DEFINED DEFINED DEFINED DEFINED DEFINED DEFINED Since Delphi.Net
MSWINDOWS DEFINED DEFINED not defined not defined not defined not defined not defined Indicates that the operating environment is Windows. Use MSWINDOWS to test for any flavor of the Windows platform instead of WIN32.
WIN32 DEFINED not defined not defined not defined not defined not defined not defined Target platform is the native 32-bit Windows platform.
WIN64 not defined DEFINED not defined not defined not defined not defined not defined Target platform is 64-bit Windows.
*New* in XE2/x64
MACOS not defined not defined DEFINED DEFINED DEFINED not defined DEFINED Target platform is OS X.
*New* in XE2/OSX
MACOS32 not defined not defined DEFINED DEFINED DEFINED not defined not defined Target platform is 32-bit OS X.
*New* in XE2/OSX
MACOS64 not defined not defined not defined not defined not defined not defined DEFINED Target platform is 64-bit OS X.
*New* in XE8/OSX
LINUX not defined not defined not defined not defined not defined not defined not defined Since Kylix
LINUX32 not defined not defined not defined not defined not defined not defined not defined Since Kylix
POSIX not defined not defined DEFINED DEFINED DEFINED DEFINED DEFINED Since Kylix
POSIX32 not defined not defined DEFINED DEFINED DEFINED DEFINED DEFINED Since Kylix
POSIX64 not defined not defined not defined not defined not defined not defined DEFINED Since Kylix
ANDROID not defined not defined not defined not defined not defined DEFINED not defined Defined if the target platform is Android.
*New* in XE5
ANDROID32 not defined not defined not defined not defined not defined DEFINED not defined Since XE8/iOSarm64
CPU CPU386 DEFINED not defined DEFINED not defined DEFINED not defined not defined Indicates that the CPU is an Intel 386 or later.
CPUX86 DEFINED not defined DEFINED not defined DEFINED not defined not defined CPU is an Intel 386 or later on any platform.
*New* in XE2/x64
CPUX64 not defined DEFINED not defined not defined not defined not defined not defined The CPU supports the x86-64 instruction set, and is in a 64-bit environment.
*New* in XE2/x64
CPU32BITS DEFINED not defined DEFINED DEFINED DEFINED DEFINED not defined The CPU is in a 32-bit environment, such as DCC32.EXE.
*New* in XE8
CPU64BITS not defined DEFINED not defined not defined not defined not defined DEFINED The CPU is in a 64-bit environment, such as DCC64.EXE.
*New* in XE8
CPUARM not defined not defined not defined DEFINED not defined DEFINED DEFINED Defined if the CPU is based on the ARM architecture, such as the Delphi mobile compiler for the iOS device (DCCIOSARM.EXE).
*New* in XE4/iOS
CPUARM32 not defined not defined not defined DEFINED not defined DEFINED not defined The CPU is in a 32-bit ARM environment, such as DCCIOSARM.EXE.
*New* in XE8
CPUARM64 not defined not defined not defined not defined not defined not defined DEFINED The CPU is in a 64-bit ARM environment, such as DCCIOSARM64.EXE.
*New* in XE8
Availability
ALIGN_STACK not defined not defined DEFINED not defined DEFINED not defined not defined Defined in code that may be shared with the OS X compiler and another compiler on another platform such as Linux that does not have a rigid stack alignment requirement. For more information, see Eli Boling's blog at http://blogs.embarcadero.com/eboling/2009/05/20/5607.
*New* in XE2/OSX
ASSEMBLER DEFINED DEFINED DEFINED not defined DEFINED not defined not defined Assembler syntax is accepted.
AUTOREFCOUNT not defined not defined not defined DEFINED DEFINED DEFINED DEFINED Defined for compilers that use automatic reference counting, such as the Delphi mobile compilers.
*New* in XE4/iOS
EXTERNALLINKER not defined not defined not defined DEFINED not defined DEFINED DEFINED Defined for compilers that have an external linker and the LLVM code generator; the Delphi mobile compilers have the external ld linker and use LLVM as code generator.
*New* in XE4/iOS
UNICODE DEFINED DEFINED DEFINED DEFINED DEFINED DEFINED DEFINED UNICODE is defined as the default string type.
CONDITIONALEXPRESSIONS DEFINED DEFINED DEFINED DEFINED DEFINED DEFINED DEFINED Tests for the use of the $IF directive.
ELF not defined not defined not defined not defined not defined not defined not defined Defined when targeting Executable and Linkable Format (ELF) files.
NEXTGEN not defined not defined not defined DEFINED DEFINED DEFINED DEFINED Defined for compilers (such as the Delphi mobile compilers) that use "next-generation" language features, such as 0-based strings.
*New* in XE4/iOS
PC_MAPPED_EXCEPTIONS not defined not defined DEFINED not defined DEFINED not defined not defined Defined when compiling on a platform or for a target platform that uses address maps instead of stack frames to unwind exceptions (such as OS X).
*New* in XE2.
PIC never never always DEFINED never always DEFINED always DEFINED never Defined for platforms that require Position-Independent Code (PIC), such as OS X.
UNDERSCOREIMPORTNAME DEFINED not defined DEFINED not defined DEFINED not defined not defined Defined for compilers that add a leading underscore (for example, in names of dynamic libraries imported from Mac OS).
*New* in XE4/iOS
WEAKREF DEFINED DEFINED DEFINED DEFINED DEFINED DEFINED DEFINED Defined for compilers that can use weak references (the [weak] attribute).
*New* in XE4/iOS
WEAKINSTREF not defined not defined not defined DEFINED DEFINED DEFINED DEFINED Defined when weak references are defined for instances.
*New* in XE4/iOS
WEAKINTFREF DEFINED DEFINED DEFINED DEFINED DEFINED DEFINED DEFINED Defined when weak references are defined for interfaces.
*New* in XE4/iOS

In the table column heads:

Using Conditional Defines for the Compiler Version

For example, to determine the version of the compiler and run-time library that were used to compile your code, you can use {$IF} with the CompilerVersion, RTLVersion and other constants:

 {$IFDEF CONDITIONALEXPRESSIONS}
    {$IF CompilerVersion >= 17.0}
      {$DEFINE HAS_INLINE}
    {$IFEND}
    {$IF RTLVersion >= 14.0}
      {$DEFINE HAS_ERROUTPUT}
    {$IFEND}
 {$ENDIF}

See the table of Compiler Versions for a list of version numbers associated with various released Delphi compilers.

Predefined Constants

Constants can be more powerful than conditionals because you can use constants programmatically in Delphi code. Conditionals, on the other hand, are accepted only inside conditional compiler directives such as {$IF} and {$IFDEF}.

There are three important constants available:

  • System.RTLVersion is a constant defined as the version of the run-time library. For Berlin, RTLVersion is 31.
  • System.CompilerVersion is a constant defined as the version of the current Delphi compiler. For Berlin, CompilerVersion is 31.
  • FMX.Types.FireMonkeyVersion is a constant defined as the version of the current FireMonkey library. For Berlin, FireMonkeyVersion is 24.

See Also