http://www.uweraabe.de/Blog/2016/01/22/on-conditional-compilation/

http://www.uweraabe.de/Blog/2016/01/22/on-conditional-compilation/
http://www.uweraabe.de/Blog/2016/01/22/on-conditional-compilation

Comments

  1. How will this be helpful baking these constants into the System.pas?

    Do you expect that the old versions will get an update to know the new constants RTLVersion_Atlantis = 99.0; too?

    {$IF RTLVersion < RTLVersion_Atlantis}
    Result := nil;
    {$ELSE}
    Result := TBrainReader.Create( User );
    {$ENDIF}

    This will not compile unless you define the constant.

    There should be an official VersionConst.inc/VersionConst.pas (simply including the inc) managed by EMBA and published through a VCS you can link to.

    That would be helpful.

    ReplyDelete
  2. Oliver Münzberg You are right! I overlooked that completely. +1 for the idea with those official files.

    ReplyDelete
  3. There is nothing wrong ...

    {$IF CompilerVersion >= CompilerVersion_XE2}

    is just more readable to me than

    {$IFDEF DELPHI16_UP}

    I know DELPHI16_UP includes also we are for sure dealing with Delphi

    ReplyDelete
  4. Stefan Glienke 1. Each library introduces its own copy. 2. It uses the old IFDEF approach.
    I personally prefer a (probably precompiled) unit with those declared constants located deep down in the system library path visible for everyone. The advantages of the $IF approach are the ability to compare against values and simultaneously using these values in plain source code.

    ReplyDelete
  5. Uwe Raabe https://github.com/project-jedi/jedi?files=1 has files exposing both version and feature based defines. The main file jedi.inc is for Delphi and FPC. A smaller file is for Kylix only. It's maintained well.

    ReplyDelete
  6. Actually, the feature based conditionals are much more usable that the version based ones. The programmer shouldn't have to worry about which language feature or library was introduced with which Delphi version. That can be solved once.

    ReplyDelete
  7. Daniela Osterhagen the thing is that some features are more stable in some Delphi versions than others (;

    ReplyDelete
  8. Jeroen Wiert Pluimers And a feature like `record helper` doesn't tell about the existence of TStringHelper or TIntegerHelper, let alone the level of implementation (like string.ToHexString f.i). There may be cases when such a feature define is sufficient, but I doubt it will cover the majority of needs.

    ReplyDelete
  9. Uwe Raabe can you do `if defined(TStringHelper)` ?

    ReplyDelete
  10. Jeroen Wiert Pluimers Probably not. Seems to return `false` in Seattle while not Defined succeeds.

    ReplyDelete
  11. Maybe a "Intrinsic Types" define needs to be added to Jedi.inc? But this won't help with the level of the intrinsic helper (as Uwe Raabe mentions above).

    ReplyDelete
  12. Nicholas Ring Both indeed - it should be added as well as it would not solve that issue. Actually I don't see that much benefit in these feature defines, which might just be caused by my workflow. When I implement a new feature or extend or refactor existing code I usually code for the latest version. Then I step down to each previous version and react when the compiler complains. Therefore I can easily spot the affected version to introduce a condition. Because I mostly go for RTLVersion a simple Ctrl-Click reveals the number to check for. It's plain easy and I rarely (never?) have the need for an include file.

    ReplyDelete
  13. Uwe Raabe I understand where you are coming from. I think the idea of the feature defines are more for code that is to be compatible between Delphi and Free Pascal (just guessing here but it sounds reasonable :-) )

    ReplyDelete
  14. Using $IF is a major pita because of $IFEND or $ENDIF depending on compiler version and $LEGACYIFEND setting.

    Uwe Raabe The compiler versions are wrong. They are being counted since TP and thus Seattle is 30. This means unless EMBT decides to progress the RTL independently from the compiler and change the way they are increasing these numbers both are exactly the same.

    Oliver Münzberg How is

    {$IF CompilerVersion >= CompilerVersion_XE2}

    any more readable than

    {$IFDEF DelphiXE2_UP}

    ?

    ReplyDelete
  15. So if you want to do the $IF approach then get rid with the version checking yourself and declare these consts as following:

    const
      DelphiXE = CompilerVersion = 22;
      DelphiXE2 = CompilerVersion = 23;
      DelphiXE3 = CompilerVersion = 24;
      DelphiXE4 = CompilerVersion = 25;
      DelphiXE5 = CompilerVersion = 26;
      DelphiXE6 = CompilerVersion = 27;
      DelphiXE7 = CompilerVersion = 28;
      DelphiXE8 = CompilerVersion = 29;
      Delphi10Seattle = CompilerVersion = 30;

      DelphiXEOrGreater = CompilerVersion >= 22;
      DelphiXE2OrGreater = CompilerVersion >= 23;
      DelphiXE3OrGreater = CompilerVersion >= 24;
      DelphiXE4OrGreater = CompilerVersion >= 25;
      DelphiXE5OrGreater = CompilerVersion >= 26;
      DelphiXE6OrGreater = CompilerVersion >= 27;
      DelphiXE7OrGreater = CompilerVersion >= 28;
      DelphiXE8OrGreater = CompilerVersion >= 29;
      Delphi10SeattleOrGreater = CompilerVersion >= 30;


    Now you can just write:

      {$IF DelphiXE3OrGreater}
        result := S.ToUpper;
      {$ELSE}
        result := Uppercase(S);
      {$IFEND}

    Which is also backwards compatible because the compiler (at least in XE and up, haven't checked any older versions) just evaluates a non existing value as False.

    ReplyDelete

Post a Comment