【发布时间】:2021-12-31 13:29:32
【问题描述】:
如果新建多设备应用项目,设置Project > Option > Compiling > Optimization : True,然后将下面的代码复制到unit1.pas:
unit Unit1;
interface
uses
System.SysUtils,
FMX.Forms,
FMX.StdCtrls,
System.Classes,
FMX.Types,
FMX.Controls,
FMX.Controls.Presentation;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
FKey: integer;
public
end;
var
Form1: TForm1;
implementation
{$R *.fmx}
procedure TForm1.Button1Click(Sender: TObject);
begin
FKey := 2;
var LCompareKey: integer := 2;
AtomicCmpExchange(FKey{target}, LCompareKey{NewValue}, LCompareKey{Comparand});
if FKey <> LCompareKey then raise Exception.Create('Error 2');
TThread.queue(nil,
procedure
begin
if LCompareKey <> FKey
then raise Exception.Create('Error 3');
end);
end;
end.
为什么这段代码在 if FKey <> LCompareKey then raise Exception.Create('Error 2'); 上的 Win32 上会崩溃?
我正在使用 Delphi 10.4 Sydney Update 3。我还没有在 Delphi 11 Alexandria 中尝试过,所以我不知道它是否在那个版本中工作。
除了停用优化之外,还有其他解决方法吗?
另一个问题——激活优化真的安全吗?
【问题讨论】:
-
如果变量被捕获,似乎 codegen 被破坏了。试试
TInterlocked.CompareExchange -
是的 TInterlocked.CompareExchange 工作得很好(奇怪,因为它只在内部使用 atomicComExchange 和内联),但是 AtomicCmpExchange 已经在任何地方使用,不仅在我的代码中,而且在层代码中:(你知道它是否是亚历山大也崩溃了?
-
@DavidHeffernan :( 没有人是完美的,我猜这个编译器也不要绝望 :( 我会在 QP 再次工作时添加一个条目,因为 QP 也不完美 :(
-
在 Delphi 11 Alexandria 上也失败了