Delphi "default" keyword with Record types in older Delphi versions
Asked Answered
B

1

10

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?

Baler answered 15/7, 2016 at 10:3 Comment(4)
It finalizes/initializes fields of managed types as well.Weidar
@LURD, I can understand the "initializes" part. but when does does it finalizes the variable?Baler
@Baler for example, clearing memory from dynamic arrays and stings, if the deleted record was the last reference. Another example is unlinking interface type reference-counted objects. see docwiki.embarcadero.com/Libraries/XE7/en/System.FinalizeSmithy
Default was introduced in D2009, see: #8460537Selfmastery
S
19

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.
Skirling answered 15/7, 2016 at 10:12 Comment(2)
The compiler hint: [Hint] DDetours.pas(1919): Expression needs no Initialize/Finalize. So, should I simply remove the Finalize(Inst); or should I turn the hint off?Baler
Up to you. Do it either way. I would probably remove the Finalize.Skirling

© 2022 - 2024 — McMap. All rights reserved.