Nested constants of nested structured types are unsupported?

delphi, pascal

Solution

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

Problem

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?

Original source