gpt4 book ai didi

delphi - AtomicCmpExchange() 坏了吗?

转载 作者:行者123 更新时间:2023-12-04 14:45:55 31 4
gpt4 key购买 nike

如果你创建一个新的多设备应用项目,设置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.

为什么这段代码在 Win32 上崩溃 if FKey <> LCompareKey then raise Exception.Create('Error 2');

我正在使用 Delphi 10.4 Sydney Update 3。我还没有在 Delphi 11 Alexandria 中尝试过,所以我不知道它是否适用于那个版本。

除了停用优化之外,是否有任何解决方法?

另一个问题——激活优化真的安全吗?

最佳答案

是的,AtomicCmpExchange 的代码生成在打开优化时在 Win32 编译器上被破坏。

问题与 TThread.Queue 调用中发生的匿名方法变量捕获结合使用。如果没有变量捕获,AtomicCmpExchange 的汇编代码会正确生成。

该问题的解决方法是使用 TInterlocked.CompareExchange

...
var LCompareKey: integer := 2;
TInterlocked.CompareExchange(FKey{target}, LCompareKey{NewValue}, LCompareKey{Comparand});
if FKey <> LCompareKey then raise Exception.Create('Error 2');
...

TInterlocked.CompareExchange 函数仍然使用 AtomicCmpExchange,但在调用位置它通过参数而不是直接处理捕获的变量,并且在这些情况下生成的代码是正确的。

class function TInterlocked.CompareExchange(var Target: Integer; Value, Comparand: Integer): Integer;
begin
Result := AtomicCmpExchange(Target, Value, Comparand);
end;

另一个不太理想的解决方案是使用 {$O-} 编译器指令关闭围绕损坏的方法 Button1Click 的优化,然后使用 { $O+}

由于 AtomicCmpExchange 是 Delphi 内部函数,它的代码在调用时由编译器直接生成,错误的代码生成只会影响该过程,而不影响一般代码 - 换句话说,匿名方法捕获在其他代码(除非编译器中存在其他错误,与此特定代码无关)。

在RTL中其他使用AtomicCmpExchange的地方,没有涉及变量捕获的代码,所以RTL、VCL和FMX代码不受这个问题影响,可以在里面开启优化申请。

注意:编译器中可能存在其他我们不知道的优化错误。

关于delphi - AtomicCmpExchange() 坏了吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70057444/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com