Delphi 中全局变量和基于堆的变量总是不稳定的吗?

问题描述 投票:0回答:1

我见过类似的问题(例如herehere),但从未见过明确的答案。假设我们有以下代码:

..
I:= 1;
I:= 2;
..

Delphi 编译器是否保证第一个赋值永远不会被优化器消除,并通过将数据写入

I
变量的内存地址来实现,而不仅仅是某个处理器寄存器,如果
I
是全局的或基于堆的(例如对象的字段)变量?

delphi optimization volatile
1个回答
3
投票

启用优化后,至少在某些情况下,上面的代码将被优化以删除第一个分配。所以这可能不是一个很好的例子! 通过这个最小的例子就可以看出这一点:

program OptimiseMe; {$APPTYPE CONSOLE} {$O+}//switch optimisations on var I: Integer; begin I := 1; I := 2; if I>0 then ; end.

但是,我从未遇到过编译器将全局或基于堆的变量优化到寄存器中的问题。它似乎总是把它写回记忆中。但我确信您不会在文档中找到任何保证这一点的内容。

但是,这与 MSVC 易失性不同,因为缓存会妨碍并且不使用内存屏障或栅栏。即使当 Delphi 编译器发出将值写入内存的指令时,它也会首先进入正在运行代码的处理器的缓存。在缓存同步之前,在其他处理器上执行的代码将无法看到该写入。

如果您想在线程之间共享这样的变量,最简单的方法可能是使用 InterlockedXXX 函数来强制执行必要的屏障并确保所有线程都具有一致的变量视图。

注意

:当你谈论 volatile 时,你需要小心,因为有很多不同的定义。 C 和 C++ 标准中定义的含义是之一。 MSVC 编译器具有符合标准但更强大的定义。 Java 和 C# 又有所不同。这里有很多复杂性,InterlockedXXX 函数是隐藏这种复杂性的好方法。

© www.soinside.com 2019 - 2024. All rights reserved.