嵌套结构化类型的嵌套常量是不受支持的?

时间:2013-04-27 02:51:37

标签: delphi pascal

尽管Delphi引用了什么

  

结构化类型可以包含其他结构化类型;一个类型可以有无限级别的结构

值得注意的例外是结构化类型常量

  

不能包含任何级别的文件类型值

我发现我不能将记录常量用作相同类型的数组常量的元素。

测试用例

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 }

我用几个Borland编译器测试了这个代码,它们都表现出相同的行为。 UPD:对于FPC也是如此,但不适用于GPC(!)。

问题(S)

这里发生了什么?我是否更正问题标题中的“嵌套结构类型的嵌套常量不受支持”结论?对问题的任何更多分析?

2 个答案:

答案 0 :(得分:5)

看来这是不可能的,其根本原因是ZeroRec不是一个真正的常量,它更像是一个初始化的静态变量。

如果指定了{$WRITEABLECONST ON},则可以轻易地更改它。即使使用$ WRITEABLECONST OFF,也可以通过某些创意类型转换(在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.

这将输出

0

2

简单类型的行为也很明显,

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

按预期编译,但是

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

给出[DCC错误] Project3.dpr(19):E2026期望的常量表达式

答案 1 :(得分:4)

您宣称的内容称为Typed Constant。在这个特定情况下,它是Array Constant。文件说明(强调我的):

  

要声明一个数组常量,请在声明末尾的括号中用逗号分隔数组元素的值。这些值必须用常量表达式表示。

编译器所反对的代码是您尝试使用只允许使用常量表达式的类型化常量的地方。

这是Delphi语言中最令人沮丧的领域之一,因为语言迫使你重复自己。