const记录参数是否放在堆栈中?

dan*_*gph 5 delphi stack

假设我有一个名为的记录类型TSomeRec:

type
  TSomeRec = record
    // ...
  end;
Run Code Online (Sandbox Code Playgroud)

...以及一个带有const TSomeRec参数的过程:

procedure SomeProc(const someRec: TSomeRec);
begin
  // ...
end;
Run Code Online (Sandbox Code Playgroud)

SomeProc调用时,const someRec参数是作为值还是作为引用传递给堆栈的?

我问的原因是,在我正在处理的代码中,有问题的记录类型包含一个庞大的静态数组,因此是巨大的.(不,我无法改变它.)我很担心将这么大的记录放在堆栈上,我认为这const可能会有所帮助.我遇到了这个代码溢出堆栈的问题,当发生这种情况时,我只会遇到神秘的访问冲突而不是任何类型的堆栈溢出错误.

Rud*_*uis 9

这取决于.这实际上是在在线帮助中描述的,但是这里有.

在32位Windows可执行文件中(即使用WIN32定义编译的代码),如果记录不大于32位寄存器,则按原样将其推送到堆栈,即按值传递.如果记录大于寄存器,则传递指向记录的指针,即通过引用传递.这是默认的register调用约定.对于其他平台或调用约定可能有所不同,但上述情况很可能是一般情况.

DocWiki:

常量参数可以通过值或引用传递给函数,具体取决于所使用的特定编译器.要强制编译器通过引用传递常量参数,可以将[Ref]装饰器与const关键字一起使用.

但是也请参阅Delphi语言指南.它描述了如何传递各种参数,例如

设置,记录和1,2或4个字节的静态数组作为8位,16位和32位值传递.较大的集合,记录和静态数组作为32位指针传递给该值.此规则的一个例外是记录总是直接在cdecl,stdcall和safecall约定下的堆栈上传递; 以这种方式传递的记录的大小向上舍入到最近的双字边界.

不过,对于较新的编译器来说,这已经改变了.

但可以肯定的是,您可以随时查阅CPU视图.在那里你可以看到会发生什么.