next up previous contents
Next: Messages Up: Using conditionalsMessages and Previous: Using conditionalsMessages and

Conditionals

  The rules for using conditional symbols are the same as under Turbo Pascal. Defining a symbol goes as follows:

{$Define Symbol }
From this point on in your code, the compiler know the symbol Symbol Symbols are, like the Pascal language, case insensitive.

You can also define a symbol on the command line. the -dSymbol option defines the symbol Symbol. You can specify as many symbols on the command line as you want.

Undefining an existing symbol is done in a similar way:

{$Undef Symbol }
If the symbol didn't exist yet, this doesn't do anything. If the symbol existed previously, the symbol will be erased, and will not be recognized any more in the code following the {$Undef ...} statement.

You can also undefine symbols from the command line with the -u command-line switch..

To compile code conditionally, depending on whether a symbol is defined or not, you can enclose the code in a {$ifdef Symbol} .. {$endif} pair. For instance the following code will never be compiled :

{$Undef MySymbol}
{$ifdef Mysymbol}
  DoSomething;
  ...
{$endif}

Similarly, you can enclose your code in a {$Ifndef Symbol} .. {$endif} pair. Then the code between the pair will only be compiled when the used symbol doesn't exist. For example, in the following example, the call to the DoSomething will always be compiled:

{$Undef MySymbol}
{$ifndef Mysymbol}
  DoSomething;
  ...
{$endif}

You can combine the two alternatives in one structure, namely as follows

{$ifdef Mysymbol}
  DoSomething;
{$else}
  DoSomethingElse
{$endif}
In this example, if MySymbol exists, then the call to DoSomething will be compiled. If it doesn't exist, the call to DoSomethingElse is compiled.

The Free Pascal compiler defines some symbols before starting to compile your program or unit. You can use these symbols to differentiate between different versions of the compiler, and between different compilers. In table (2.1), a list of pre-defined symbols is givengif. In that table, you should change v with the version number of the compiler you're using, r with the release number and p with the patch-number of the compiler. 'OS' needs to be changed by the type of operating system. Currently this can be one of DOS, GO32V2, LINUX, OS2, WIN32, MACOS, AMIGA or ATARI. This symbol is undefined if you specify a target that is different from the platform you're compiling on. the -TSomeOS option on the command line will define the SomeOS symbol, and will undefined the existing platform symbolgif.

  

Free
VERv
VERv_r
VERv_r_p
OS
Table 2.1: Symbols defined by the compiler.

As an example : Version 0.9.1 of the compiler, running on a Linux system, defines the following symbols before reading the command line arguments: FPC, VER0, VER0_9, VER0_9_1 and LINUX. Specifying -TOS2 on the command-line will undefine the LINUX symbol, and will define the OS2 symbol.

Remark: Symbols, even when they're defined in the interface part of a unit, are not available outside that unit.

Free Pascal supports the {$IFOPT } directive for Turbo Pascal compatibility, but doesn't act on it. It always rejects the condition, so code between {$IFOPT } and {$Endif} is never compiled.

Except for the Turbo Pascal constructs, from version 0.9.8 and higher, the Free Pascal compiler also supports a stronger conditional compile mechanism: The {$If } construct.

The prototype of this construct is as follows :

{$If expr}
  CompileTheseLines;
{$else}
  BetterCompileTheseLines;
{$endif}
In this directive expr is a Pascal expression which is evaluated using strings, unless both parts of a comparision can be evaluated as numbers, in which case they are evaluated using numbersgif. If the complemete expression evaluates to '0', then it is considered false and rejected. Otherwise it is considered true and accepted. This may have unsexpected consequences :
{$If 0}
Will evaluate to False and be rejected, while
{$If 00}
Will evaluate to True.

You can use any Pascal operator to construct your expression : =, <>, >, <, >=, <=, AND, NOT, OR and you can use round brackets to change the precedence of the operators.

The following example shows you many of the possibilities:

{$ifdef fpc}

var
   y : longint;
{$else fpc}

var
   z : longint;
{$endif fpc}

var
   x : longint;

begin

{$if (fpc_version=0) and (fpc_release>6) and (fpc_patch>4)}
{$info At least this is version 0.9.5}
{$else}
{$fatalerror Problem with version check}
{$endif}

{$define x:=1234}
{$if x=1234}
{$info x=1234}
{$else}
{$fatalerror x should be 1234}
{$endif}

{$if 12asdf and 12asdf}
{$info $if 12asdf and 12asdf is ok}
{$else}
{$fatalerror $if 12asdf and 12asdf rejected}
{$endif}

{$if 0 or 1}
{$info $if 0 or 1 is ok}
{$else}
{$fatalerror $if 0 or 1 rejected}
{$endif}

{$if 0}
{$fatalerror $if 0 accepted}
{$else}
{$info $if 0 is ok}
{$endif}

{$if 12=12}
{$info $if 12=12 is ok}
{$else}
{$fatalerror $if 12=12 rejected}
{$endif}

{$if 12<>312}
{$info $if 12<>312 is ok}
{$else}
{$fatalerror $if 12<>312 rejected}
{$endif}


{$if 12<=312}
{$info $if 12<=312 is ok}
{$else}
{$fatalerror $if 12<=312 rejected}
{$endif}

{$if 12<312}
{$info $if 12<312 is ok}
{$else}
{$fatalerror $if 12<312 rejected}
{$endif}

{$if a12=a12}
{$info $if a12=a12 is ok}
{$else}
{$fatalerror $if a12=a12 rejected}
{$endif}

{$if a12<=z312}
{$info $if a12<=z312 is ok}
{$else}
{$fatalerror $if a12<=z312 rejected}
{$endif}


{$if a12<z312}
{$info $if a12<z312 is ok}
{$else}
{$fatalerror $if a12<z312 rejected}
{$endif}

{$if not(0)}
{$info $if not(0) is OK}
{$else}
{$fatalerror $if not(0) rejected}
{$endif}

{$info *************************************************}
{$info * Now have to follow at least 2 error messages: *}
{$info *************************************************}

{$if not(0}
{$endif}

{$if not(<}
{$endif}

end.
As you can see from the example, this construct isn't useful when used with normal symbols, but it is if you use macros, which are explained in section (2.3), they can be very useful. When trying this example, you must switch on macro support, with the -Sm command-line switch.


next up previous contents
Next: Messages Up: Using conditionalsMessages and Previous: Using conditionalsMessages and

Michael Van Canneyt
Thu Sep 10 14:04:11 CEST 1998