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

时间:2011-12-13 10:21:57

标签: delphi optimization compiler-construction volatile

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

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

Delphi编译器保证优化器永远不会消除第一个赋值,并通过将数据写入I变量的内存地址来实现,而不仅仅是某个处理器寄存器,如果I是全局或基于堆(例如对象的字段)变量?

1 个答案:

答案 0 :(得分: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函数是隐藏这种复杂性的好方法。