17

In XE5 all conditional compilations such as

{$IFDEF MSWINDOWS} 

are replaced with

{$IF defined(MSWINDOWS)}

For example System.Diagnostics.pas in XE4 had

...
implementation

{$IFDEF MSWINDOWS}
uses Winapi.Windows;
{$ENDIF}
{$IFDEF MACOS}
uses Macapi.Mach;
{$ENDIF}

{ TStopwatch }
...

and now in XE5 it looks like:

...
implementation
{$IF defined(MSWINDOWS)}
uses Winapi.Windows;
{$ELSEIF defined(MACOS)}
uses Macapi.Mach;
{$ELSEIF defined(POSIX)}
uses Posix.Time;
{$ENDIF}

{ TStopwatch }
...

Is there any particular reason I should migrate my similar invocations as well?

Gad D Lord
  • 6,620
  • 12
  • 60
  • 106
  • 12
    Uhm, because with `$IFDEF` you can't use `$ELSEIF` ? – TLama May 11 '14 at 20:31
  • I guessed so as well but maybe there are some other benefits? The change is quite massive - all around all units. – Gad D Lord May 11 '14 at 20:35
  • Very hard to see past the reason that @TLama gave. – David Heffernan May 11 '14 at 21:10
  • $IF accepts an expression as argument whereas IFDEF just symbol name hence you do not need use ugly nested conditional blocks any more if your projects have rich conditional compilations. I'd say they just throw obsolete directives away as we did once $IF directive has been introduced years ago. – pf1957 May 11 '14 at 21:24
  • `$IF Defined(SYM)` is merely more syntactically advanced equivalent of `$IFDEF SYM`. Unless you have more complex expression for `$IF` or specific requirement for branching with `$ELSEIF` there are no reasons. – Free Consulting May 11 '14 at 23:07
  • There appears to be a "refreshing" of the VCL and RTL and bringing the coding standards more up to modern Delphi versions in general. This is just a "personal preference" of someone on the Delphi team, basically. – Warren P May 13 '14 at 17:19

1 Answers1

21

According to the Delphi documentation:

http://docwiki.embarcadero.com/RADStudio/Rio/en/Conditional_compilation_%28Delphi%29

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.

The {$IFDEF} and {$IFNDEF} only allow you to work with defines previously set by {$DEFINE ...}.
However the {$IF ..} directive is much more flexible, because:

Delphi identifiers cannot be referenced in any conditional directives other than {$IF} and {$ELSEIF}.

const LibVersion = 6;  //One constant to define the libversion.
{$IF LibVersion >= 10.0}
  do stuff that covers LibVersion 10,11 and 12
{$ELSEIF Libversion > 5.0}
  do other stuff that covers LibVersion 6,7,8,9
{$IFEND}

If you tried to do that with defines you'd have to do

{$DEFINE Lib1}
{$DEFINE Lib2}
{$DEFINE Lib3}
{$DEFINE Lib4}
{$DEFINE Lib5}
{$DEFINE Lib6} //all previous versions have to be defined.

{$IFDEF Lib10}
  do stuff that covers LibVersion 10, 11 and 12
{$ELSE}
  {$IFDEF Lib6}
    do stuff that covers LibVersion 6,7,8,9
  {$ENDIF}
{$ENDIF}

It's just a slightly more advanced version of processing the defines.
The {$IF ..} notation is a bit more powerful and it allows you to query constant expressions and not just defines.

The {$IF ..} directive was introduced in Delphi 6.

I guess Embarcadero decided to clean up the code base.

Shaun Roselt
  • 1,650
  • 5
  • 18
  • 44
Johan
  • 74,508
  • 24
  • 191
  • 319