Delphi是否有任何与C的volatile变量等价的东西?

在C和C ++中,变量可以标记为volatile ,这意味着编译器不会对其进行优化,因为它可以在声明对象外部进行修改。 在Delphi编程中是否有相同的东西? 如果不是关键字,也许可以解决?

我的想法是使用绝对 ,但我不确定,这可能会引入其他副作用。

简答:不。

但是,如果您遵循以下方法,我不知道编译器的保守方法会改变读取或写入次数的任何情况:

在读取跨线程可见位置时,在进行任何进一步操作之前将其值保存到本地; 同样,限制写入单个分配。

当在表达式之间调用非内联方法时,Delphi编译器不对非本地位置表达式执行公共子表达式消除(CSE),因为编译器不进行过程间优化,因此即使对于单个进程也不正确 – 线程代码。

因此,您可能希望使用InterlockedExchange()来执行读取和写入以强制执行此操作; 此外,这将导致完整的内存屏障,因此处理器也不会重新排序读取和写入。

根据Delphi移动开发语言白皮书,Delphi的移动编译器自首次引入以来支持[volatile]属性:

volatile属性用于标记可能由不同线程更改的字段,因此代码生成不会优化复制寄存器或其他临时内存位置中的值。

您可以使用volatile属性标记以下声明:

  • 变量(全局和本地)
  • 参数
  • 记录或类的字段。

您不能使用volatile属性标记以下声明:

  • 类型
  • 程序,function或方法
  • 表达式
 type TMyClass = class private [volatile] FMyVariable: TMyType; end; 

从Delphi 10.1 Berlin开始,桌面编译器现在也支持[volatile]

所有编译器支持的属性

现在,所有Delphi编译器都支持以下属性:

  • 不安全
  • 挥发物

我不知道任何等价物,也不认为绝对指令会对你有帮助。 absolute允许你有两个使用相同地址的变量,但我认为它不会阻止编译器优化对该内存的引用。

我想你可以用指针自己管理它。 无论编译器如何优化指针值的优化,它都不应该假设存储在地址中的值与上次读取时的值相同,但这是纯粹的推测。

Delphi for .Net也没有关键字,但.Net平台具有utilfunction。 请参见Thread.VolatileRead和Thread.VolatileWrite 。

使用动态分配的指针?

 var MyVarPtr: ^integer; begin New(MyVarPtr); MyVarPtr^ := 5; ... 

这应该使编译器不使用寄存器来获取整数值(但它仍然可以使用一个用于地址)。 不过,我不确定这与挥发性有什么不同。