On Friday I had a brain fade moment (which I don't seems to have recovered from). I'm coding up app to help people find and implement OTA code and the app uses TVirtualStringTree (a lot). So I defined a record for the tree as:

On Friday I had a brain fade moment (which I don't seems to have recovered from). I'm coding up app to help people find and implement OTA code and the app uses TVirtualStringTree (a lot). So I defined a record for the tree as:

Type
TTreeData = Record
...
End;

I've then been referring to the record as follows:

Var
NodeData : ^TTreeData;

Which allows my to do:

...
NodeData := vstInterfaces.GetNodeData(Node);
NodeData.FFileIndex := ....
...

I then wanted to pass the record to another function and since you can't define pointers to types in a function I created this type:

Type
PTreeData = ^TTreeData;

Then the function:

Procedure MyFunc(NodeData : PTreeData);

However I could not pass NodeData as defined above (^TTreeData) to this function without redefining it as:

Var
NodeData : PTreeData;

In my mind they are the same but the compiler obviously believes they are different.

Question it why?

Comments

  1. The problem $T is that it's a two-edged sword as it makes code that looks valid fail to compile because the compiler in the $T+ state (a.k.a. $TypedAddress on state) never got updated to:

    - handle @ to an array create a pointer to the element of that array
    - handle @ to resourcestrings to become PResStringRec

    (and likely more examples)

    Which means the below programs fail to compile.

    The alternative (adding way more {$T+} compatible overloads to the RTL/VCL/FMX) was never done either, so now we're stuck with {$T-}

    program TypedAddressDirectiveWithCharArrays;

    {$APPTYPE CONSOLE}

    {$TypedAddress on}

    uses
    Winapi.Windows;

    var
    TimeZone: string;
    TZ: TTimeZoneInformation;

    begin
    TimeZone := 'Coordinated Universal Time';
    StringToWideChar(TimeZone,@(TZ.StandardName), SizeOf(TZ.StandardName) div SizeOf(WideChar));
    end.

    (*

    [dcc32 Error] TypedAddressDirectiveWithCharArrays.dpr(16): E2010 Incompatible types: 'PWideChar' and 'Pointer'

    In the System unit:

    implicit types:

    PWideChar = WideChar;
    PChar = PWideChar

    explicit:

    function StringToWideChar(const Source: UnicodeString; Dest: PWideChar; DestSize: Integer): PWideChar;



    In the Winapi.Windows unit:

    type
    WCHAR = WideChar;

    PTimeZoneInformation = ^TTimeZoneInformation;
    _TIME_ZONE_INFORMATION = record
    Bias: Longint;
    StandardName: array[0..31] of WCHAR;
    StandardDate: TSystemTime;
    StandardBias: Longint;
    DaylightName: array[0..31] of WCHAR;
    DaylightDate: TSystemTime;
    DaylightBias: Longint;
    end;
    TTimeZoneInformation = _TIME_ZONE_INFORMATION;
    TIME_ZONE_INFORMATION = _TIME_ZONE_INFORMATION;

    *)


    program TypedAddressDirectiveWithResourceStrings;

    {$APPTYPE CONSOLE}

    {$TypedAddress on}

    uses
    System.SysConst,
    System.SysUtils;

    procedure RangeError;
    begin
    raise ERangeError.CreateRes(@SRangeError);
    end;

    begin
    end.

    (*
    [dcc32 Error] TypedAddressDirectiveWithResourceStrings.dpr(13): E2250 There is no overloaded version of 'CreateRes' that can be called with these arguments


    System unit:

    type
    PResStringRec = ^TResStringRec;
    {$IF defined(EXTERNALLINKER)}
    TResStringRec = record
    Key: MarshaledAString;
    end;
    {$ELSE}
    TResStringRec = packed record
    // 32bit = 8 bytes
    // 64bit = 16 bytes
    Module: ^HMODULE;
    Identifier: NativeUint;
    end;
    {$ENDIF}


    System.SysConst unit:

    resourcestring
    SRangeError = 'Range check error';


    SysUtils unit:

    constructor Exception.CreateRes(ResStringRec: PResStringRec);
    begin
    FMessage := LoadResString(ResStringRec);
    end;


    *)

    ReplyDelete
  2. Jeroen Wiert Pluimers Is there a QP for that?

    ReplyDelete
  3. David Millington probably not. It's from the era that beta forum postings and QC entries started to be ignored so after I saw entries http://qc.embarcadero.com/wc/qcmain.aspx?d=3223 it was OK for me.

    ReplyDelete

Post a Comment