Alister
Alister

Reputation: 6837

Why are const record parameters passed by value?

If I have a record e.g.

type
  TMyRec = record
    x : string;
  end;

And a procedure test(const x : TMyRec);. Why is that parameter passed by value (i.e. a copy is passed in) and not by reference. I would have thought from an efficiency point of view it should be passed by reference (like say an integer).

Upvotes: 3

Views: 874

Answers (1)

Alister
Alister

Reputation: 6837

It looks like this is related to the size of the record, for

procedure test(const x : TMyRec);

the type

type
  TMyRec = record
    x : Array[1..4] of byte;
  end;

would be passed by value, and

type
  TMyRec = record
    x : Array[1..5] of byte
  end;

would be passed by reference on 32 bit, for 64 bit we would need a record of 9 bytes to be passed by reference on Tokyo (10.2.3) or earlier, Rio (10.3) behaves the same on both 32 and 64 bit. Thanks to everyone who comment on my question, and provided additional references/suggestions.

See the Tokyo Documentation here. In particular

Value and constant (const) parameters are passed by value or by reference, depending on the type and size of the parameter:

...

Sets, records, and static arrays of 1, 2, or 4 bytes are passed as 8-bit, 16-bit, and 32bit values. Larger sets, records, and static arrays are passed as 32-bit pointers to the value. An exception to this rule is that records are always passed directly on the stack under the cdecl, stdcall, and safecall conventions; the size of a record passed this way is rounded upward to the nearest double-word boundary.

If you want to force a pass-by-reference, you can declare your parameter as const [ref], like so:

procedure test(const [ref] x : TMyRec);

Upvotes: 6

Related Questions