Skip to content

More undocumented Win32 language features

Following up

I received a few interesting replies to my previous post about features Borland implemented in the Win32 compiler for Delphi, but "forgot" to document. I’m sure you can find them in the comments section, but I’d like to repeat them here.

Gerriz Beuze and Rossen Assenov mentioned some other features and I checked them. These seem to be valid in the Win32 personality of Delphi 2005 too:

  • Default array properties can be overloaded, i.e. have the same name, as long as the signature, i.e. the array parameter list, is different.
    type
      TTestClass = class
      private
        function GetInts(index: Integer): Integer;
        procedure SetInts(index: Integer; const Value: Integer);
        function GetIntsS(Find: string): Integer;
        procedure SetIntsS(Find: string; const Value: Integer);
      public
        property Ints[index: Integer]: Integer read GetInts write SetInts;
          default;
        property Ints[Find: string]: Integer read GetIntsS write SetIntsS;
          default;
      end;
    
  • Identifier escape char "&" is supported. You can do something like:
    var
      &object: TObject;
    
  • Method directive "final" supported.
  • Method directive "inline" is supported. But, unlike Gerrit claimed, it also works in .NET.
  • Static class methods are supported.
  • Class properties are supported:
      private
        class function GetClassProp: Integer; static;
        class procedure SetClassProp(const Value: Integer); static;
      public
        class property P: Integer read GetClassProp write SetClassProp;
  • Compiler hint directive "experimental" is supported.
    unit SomeName experimental;
  • Classes support the "abstract" and "sealed" directives.
  • Classes can contain "const", "type" and "var" declarations:
    type
      TAbstract = class abstract
      public
        type
          TTestArray = array of Integer;
          TSealed = class sealed
            procedure DoIt(Param: Integer);
          end;
        const
          Cons = 13;
          ConsB: Integer = 12;
        var
          Y: Integer;
      end;
    

Some more

I found some more features, officially introduced in Delphi 8 and Delphi 2005 for the .NET compiler, which also work in the Win32 personality:

  • Code folding regions:
    {$REGION 'private members'}
      // ...
    {$ENDREGION}

    This is not really a surprise, since they seem to be more an IDE feature than a language feature, but the language must still know them, and not throw an error.

  • Dynamic initialization of dynamic arrays, using the Create syntax:
      type
        TDoubleArray = array of Double;
    
      var
        A: TDoubleArray;
        D: Double;
    
      begin
        A := TDoubleArray.Create(1.7, 3.9, 17.1, 39.7, 42.0);
        for D in A do
          Writeln(D:1:1);
        // etc...
    

    I’m not sure if that is actually documented anywhere, not even for the .NET compiler (where this already worked in Delphi 8, see the KnobControl demo control in the demos that come with Delphi).

But why undocumented?

It seems that some of them are not completely undocumented. The Borland Delphi 2005 Reviewer’s Guide discusses the Win32 compiler (page 59ff.). It mentions function inlining, nested types, strict private, nested consts, support for Pentium 4 SSE3 and SSE2 instruction opcodes and data types, and XML document generation (some of which I hadn’t even noticed). A BDN article by Bob Swart mentions a few new features as well, but for .NET. I tried them in Win32, and they don’t compile.

I’m not sure why the rest is undocumented though, and why Borland is not advertising these new features. Perhaps they were not finalized yet, and Borland doesn’t want to support them, right now. Perhaps they were simply forgotten in the documentation. But the fact that they are undocumented means that you should take extreme care when you use these features. One problem I noticed is with class helpers.

Class helpers

In the previous post, I mentioned class helpers. They do work, but if you try to derive from a "helped" class, you might get an internal compiler error, which means that the implementation is not fully OK yet. Like I said, always use undocumented features with care.

{ 6 } Comments

  1. Anthony Frazier | May 13, 2005 at 12:26 pm | Permalink

    Actually, experimental units are documented in 2005. The following is the help link where its documented.

    ms-help://borland.bds3/bds3guide/html/DeclarationsAndStatements.htm

    With these directives, do they actually work (i.e. are they enforced in the compiler/language), or does the compiler ignore them and not error? For some of these it’s obvious that they must work (e.g. overloaded default array properties), but for the directives it may not be so clear.

  2. Rudy Velthuis | May 13, 2005 at 2:48 pm | Permalink

    <<

    Actually, experimental units are documented in 2005.

    >>

    Oh cool, I was not aware of that.

    <<

    With these directives, do they actually work (i.e. are they enforced in the compiler/language), or does the compiler ignore them and not error? For some of these it’s obvious that they must work (e.g. overloaded default array properties), but for the directives it may not be so clear.

    >>

    Abstract, when used for classes, does not have any useful meaning I could find in the online help, so I did not test that. But the "sealed" directive is enforced, i.e. you can’t extend a sealed class.

    AFAIK, "final" is also enforced.

  3. Jim McKeeth | May 26, 2005 at 10:08 pm | Permalink

    That is some major fun! Thanks for sharing these finds!

  4. Laurent Dardenne | June 8, 2005 at 7:55 am | Permalink

    There is also the Initialize method. To initialize an array :

    A := TDoubleArray.Create(1.7, 3.9, 17.1, 39.7, 42.0);

    Writeln(’Size =’,Length(A));

    for D in A do

    Writeln(D:1:1);

    Initialize(A);

    Writeln(’Size =’,Length(A));

  5. Laurent Dardenne | June 8, 2005 at 8:27 am | Permalink

    And too, Strict private, Private, Public directive inside a record:

    unit TestRecord;

    interface

    Type

    TUrec = record

    Strict private

    StrictPrivateValue : integer;

    Private

    PrivateValue : integer;

    Public

    PublicValue: Integer;

    end;

    implementation

    end.

    program TestRec;

    {$APPTYPE CONSOLE}

    uses

    SysUtils,

    TestRecord in ‘TestRecord.pas’;

    type

    Trec = record

    Strict private

    StrictPrivateValue : integer;

    Private

    PrivateValue : integer;

    Public

    PublicValue: Integer;

    end;

    var TR : Trec;

    TUR :TUrec;

    begin

    with TR do

    begin

    StrictPrivateValeur:=1;

    PrivateValeur:=2;

    PublicValeur:=3;

    end;

    with TUR do

    begin

    //StrictPrivateValeur:=1; // error E2003 : Identifier not declared ‘StrictPrivateValeur’

    //PrivateValeur:=2; // error E2003 : Identifier not declared’PrivateValeur’

    PublicValeur:=3;

    end;

    end.

  6. Roozbeh GHolizadeh | October 5, 2005 at 11:06 am | Permalink

    Well i think this is also undocumented!

    in delphi help about virtual methods in properties stated

    "If fieldOrMethod is a method, it cannot be dynamic and, if virtual, cannot be overloaded"

    but following code compiles fine

    myclass=class

    procedure SetTestValue(invalue : integer);overload;virtual;

    procedure SetTestValue(invalue : string);overload;virtual;

    property testvalue:integer write SetTestValue;

    end;

    and doesnt compile in delphi 7!

    i also found this intresting thing(i dont know if in help stated or not)

    property only works with first overloaded procedure so the following doesnt compile!

    procedure SetTestValue(invalue : integer);overload;virtual;

    procedure SetTestValue(invalue : string);overload;virtual;

    property testvalue:string write SetTestValue;

    forgive me if all was documented and told before ;)

Post a Comment

Your email is never published nor shared. Required fields are marked *

Bad Behavior has blocked 54 access attempts in the last 7 days.

Close