5

尽管德尔福参考说

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

除了明显的例外是什么结构化类型的常量

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

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

测试用例

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(!) 则不然。

问题)

这里发生了什么?我对问题标题中的“不支持嵌套结构化类型的嵌套常量”的结论是否正确?再分析一个问题?

4

2 回答 2

5

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

如果指定了 {$WRITEABLECONST ON},则可以轻松更改它。即使 $WRITEABLECONST 关闭,它也可以通过一些创造性的类型转换来改变(在 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 Constant expression expected

于 2013-04-27T03:14:16.863 回答
4

您声明的内容称为Typed Constant。在这种特定情况下,它是一个Array Constant。文档状态(强调我的):

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

编译器对象的代码是您尝试使用类型常量的地方,其中只允许使用常量表达式。

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

于 2013-04-27T07:07:16.903 回答