I am currently trying to update an open source project from Delphi 2007 to XE2 and found some code which supposedly already works for XE2. But it is ab-using ifdef in several ways so I thought I’d blog about this to vent some steam and also possibly educate others.
(Class name changed to protect the innocents. ;-))
Please, never ever do this:
function TSomething.GetRecord(Buffer: {$IFDEF DELPHI_2009} RecordBuffer{$ELSE}PChar{$ENDIF}; GetMode: TGetMode; DoCheck: Boolean): TGetResult;
There are actually several things wrong with this code:
- Never use an ifdef for a specific Delphi version. Instead define a symbol for a specific feature like
{$ifdef DELPHI_2009} {$define SUPPORTS_TRECORDBUFFER} {$endif}
and use that one in code. Remember: Usually, new features stay with all later Delphi versions, so even the name of the conditional is wrong, it should be DELPHI_2009_AND_UP or similar, if used in that way.
- Don’t sprinkle ifdefs like this through 1000s of lines of code just because the type of a variable, parameter or function result has changed. Instead define your own type like this:
type {$ifdef SUPPORTS_TRECORDBUFFER} TMyRecordBuffer = TRecordBuffer; {$else} TMyRecordBuffer = PChar; {$endif}
and use it wherever necessary. It makes the code so much more readable.
- At least they got something right: They don’t use VERxxx all over the place but have an include file as a central place to check for compiler versions.
But: Don’t write your own version include file, instead use one from a popular open source project like Project Jedi when possible. There used to be a compilers.inc file on the interwebs, but I don’t think it is being maintained any more.
EDIT: There is DelphiVersions.inc in the Delphi Wiki, which has been updated by me and occasionally somebody else up to Delphi 11 (which is the current version now).
— 2023-04-08
</rant>