You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi XE3 x86架构下自定义record赋值异常问题咨询

问题根因

这是Delphi XE3 x86架构下的已知编译器bug,触发条件为:在记录类型的实例方法内部,将Self赋值给其他同类型记录变量,且记录大小超过12字节(即3个4字节基础字段)时:

  • 记录大小≤12字节时,编译器生成逐字段拷贝的mov指令,逻辑正常
  • 记录大小>12字节时,编译器会改用movsd块拷贝逻辑,但错误将记录第一个字段的值作为拷贝源地址,而非Self本身的内存地址。你的场景中第一个字段是FOwner,存储的是TPage实例的地址,所以实际拷贝的是TPage对象开头的内存到FSelected字段,才会出现垃圾值。
语法规范说明

你使用的FOwner.FSelected:=Self;赋值逻辑完全符合Delphi语法规范,不属于使用错误,问题完全由编译器代码生成错误导致。

可行规避方案

除了你已经在用的CopyMemory方案外,还可以选择以下更简便的处理方式:

  • 显式指定地址解引用赋值,强制编译器使用正确的源地址:
FOwner.FSelected := TParagraph(Self^);
  • 局部关闭该方法的编译优化,可避免编译器生成错误的块拷贝指令:
{$O-} // 关闭优化
procedure TPage.TParagraph.Select;
begin
  FOwner.FSelected := Self;
end;
{$O+} // 恢复优化
  • 升级编译器版本:该bug在Delphi XE7及之后的版本已经被Embarcadero官方修复,升级到更高版本可彻底解决问题。

内容的提问来源于stack exchange,提问作者loltrol

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 09:57:03