Home Are const record arguments put on the stack?
Reply: 1

Are const record arguments put on the stack?

dan-gph
1#
dan-gph Published in 2018-01-09 02:20:58Z

Suppose I have a record type called TSomeRec:

type
  TSomeRec = record
    // ...
  end;

... and a procedure that takes a const TSomeRec argument:

procedure SomeProc(const someRec: TSomeRec);
begin
  // ...
end;

When SomeProc is called, will the const someRec argument be passed on the stack as a value or as a reference?

The reason I ask is that in the code I am working on, the record type in question contains a massive static array and so is huge. (No, I cannot change that.) I am nervous about putting such a large record on the stack, and I thought that const might help. I have had problems with this code with overflowing the stack, and when that happens, I just get mysterious access violations rather than any sort of stack overflow error.

Rudy Velthuis
2#
Rudy Velthuis Reply to 2018-01-09 17:47:19Z

It depends. This is actually described in the online help, but here goes.

In 32 bit Windows executables (i.e. code compiled with WIN32 defined), if the record is not larger than a 32 bit register, it is pushed on the stack as-is, i.e. passed by value. If the record is larger than a register, a pointer to the record is passed, i.e. passed by reference. That is for the default register calling convention. It may be different for other platforms or calling conventions, but the above is very likely the general case.

DocWiki:

Constant parameters may be passed to the function by value or by reference, depending on the specific compiler used. To force the compiler to pass a constant parameter by reference, you can use the [Ref] decorator with the const keyword.

But see the Delphi Language Guide too. It describes how all kinds of parameters are passed, e.g.

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.

That has changed for newer compilers, though.

But to be sure, you can always consult the CPU view. There you can see what happens.

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.314723 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO