Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
997 views
in Technique[技术] by (71.8m points)

delphi - Nested constants of nested structured types are unsupported?

Despite of what Delphi reference says

structured types can contain other structured types; a type can have unlimited levels of structuring

with notable exception what structured typed constants

cannot contain file-type values at any level

I discovered what I cannot use record constant as an element of array constant of the same type.

Testcase

type
  MyRecord = record MyField: Integer end;

const
  Typical: array[0..1] of MyRecord = ((MyField: 0), (MyField: 1));

  { now I tried to achieve more clarity by declaring a specific constant }
  Zero: MyRecord = (MyField: 0);

  { and compiler refused to accept that }
  Bad: array[0..1] of MyRecord = (Zero, (MyField: 1));  { E2029 '(' expected but identifier 'Zero' found }

I tested this code with several Borland compilers, all of them exhibited the same behaviour. UPD: also the same for FPC, but not for GPC(!).

Question(s)

What is going on here? Am I correct with "Nested constants of nested structured types are unsupported" conclusion in the question title? Any more analysis of an issue?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

It appears that this isn't possible, the underlying cause is that ZeroRec isn't truly a constant, it is more like an initialised static variable.

If {$WRITEABLECONST ON} is specified, then it can be trivially changed. Even with $WRITEABLECONST OFF, it can be changed by some creative type casting (tested in XE2):

program Project3;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

type
  MyRecord = record MyField: Integer end;
  PMyRecord = ^MyRecord;

const
  Typical: array[0..1] of MyRecord = ((MyField: 0), (MyField: 1));

  { now I tried to achieve more clarity by declaring a specific constant }
  ZeroRec: MyRecord = (MyField: 0);
  { and compiler refused to accept that }
//  Bad: array[0..1] of MyRecord = ((MyField: Zero), (MyField: 1));  { E2029 '(' expected but identifier 'Zero' found }
begin
  try
    { TODO -oUser -cConsole Main : Insert code here }
    WriteLn(ZeroRec.MyField);
    PMyRecord(@ZeroRec)^.MyField := 2;
    WriteLn(ZeroRec.MyField);
    readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

This will output

0

2

The behaviour is also evident with simple types,

  Zero = 0;
  ZeroRec: MyRecord = (MyField: Zero);

compiles as expected, however

  Zero : Integer = 0;
  ZeroRec: MyRecord = (MyField: Zero);

gives [DCC Error] Project3.dpr(19): E2026 Constant expression expected


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
...