Delphi “default” keyword with Record types in olde

2020-07-08 07:27发布

问题:

I have this code in Delphi Detours library which I'm trying to port:

type
  TInstruction = record
    Archi: Byte; { CPUX32 or CPUX64 ! }
    AddrMode: Byte; { Address Mode }
    Addr: PByte;
    VirtualAddr: PByte;
    NextInst: PByte; { Pointer to the Next Instruction }
    OpCode: Byte; { OpCode Value }
    OpType: Byte;
    OpKind: Byte;
    OpTable: Byte; { tbOneByte,tbTwoByte,... }
    OperandFlags: Byte;
    Prefixes: Word; { Sets of Prf_xxx }
    ...
  end;

var
  Inst: TInstruction;
begin
  ...
  Inst := default (TInstruction); // <-
  Inst.Archi := CPUX;
  Pvt := PPointer(AIntf)^; // vTable !
  PCode := PPointer(Pvt + Offset)^; // Code Entry !
  Inst.NextInst := PCode;
  ...
end;

What does the "default" keyword do? I assume something like:

FillChar(Inst, SizeOf(TInstruction), 0);

Is my assumption correct?

回答1:

Default() is an undocumented intrinsic function introduced to support generics. The design of Delphi generics was heavily inspired by .net generics and you might benefit from reading the analagous documentation for .net: https://msdn.microsoft.com/en-GB/library/xwth0h0d.aspx

The purpose of Default() is to allow you to default initialize a variable. When working with generic types Default() allows you to do so for a variable whose type is generic.

If you wish to replicate the behaviour of Default() do the following:

Finalize(Inst);
FillChar(Inst, SizeOf(Inst), 0);

The call to Finalize is needed in case the type is managed. That is if the type is managed, or contains any members that are managed. Managed types include strings, dynamic arrays, interfaces, variants, anonymous methods etc.

If the type does not contain managed types then the call to Finalize may be omitted. It doesn't hurt to include it though, because the compiler will eliminate it if not needed. If you can be 100% certain that no managed types have been assigned a value then you could also omit that call.

Default initialization means the following:

  • Zero for numeric types.
  • The value with ordinal zero for enumerated types.
  • False for boolean types.
  • #0 for character types.
  • The empty string for strings.
  • The empty variant for Variant.
  • nil for classes, dynamic arrays, interfaces and anonymous methods.