InterlockedIncrement参数声明为volatile的效果是什么?

5

InterlockedIncrement和其他Interlocked操作将它们的参数声明为volatile。为什么?这样做的目的和效果是什么?


我发现了一个有关此事的激烈辩论 http://groups.google.com/group/comp.programming.threads/tree/browse_frm/thread/1fa4a82dda916b18/a886def5998f9b82?rnum=21&_done=%2Fgroup%2Fcomp.programming.threads%2Fbrowse_frm%2Fthread%2F1fa4a82dda916b18%2Ffd6be8f0b18bd62d%3F#doc_5d933de5ad5378cf - 在那里没有结论,但是有详细的解释,为什么volatile不能如最初所期望的那样工作。 - Suma
您可能还想查看对于此问题的答案:https://dev59.com/SXA65IYBdhLWcg3w1SbU。 - sbi
4个回答

8
可能的影响非常小。最有可能的意图是允许用户在不需要类型转换的情况下将带volatile限定符的变量传递给这些函数。

“effect is very minimal”是什么意思?您能提供任何参考资料吗? - n00bmind

4
为了使函数能够在普通变量和易失变量上调用,需要进行这样的操作。你不能将易失变量传递给不期望易失参数的函数中。以下代码无法编译(使用Visual Studio 2005 C++编译器测试):
void TestV(int *a)
{
  *a = 1;
}

void Test()
{
  volatile int a = 0;
  TestV(&a);
}

根据声明的内容,您可以进行以下操作:

volatile LONG a = 0;

InterlockedIncrement(&a);

由于在volatile变量上调用InterlockedIncrement可能具有意义,因此将其声明为这样似乎是明智的。


0

volatile参数可以防止编译器进行优化,从而防止对内存的读取。只要代码的可见效果相同,编译器可以进行任何优化,但这些效果在多线程场景下不被考虑,仅适用于单个线程。volatile关键字告诉编译器,该变量可能会被外部未知来源修改或读取,编译器不能消除它或省略对其的内存访问。


1
这通常适用于volatile,但在这种特殊情况下不适用。对于函数的调用者来说,无论函数是否在内部处理参数为volatile,都没有区别。 - Suma

-2
简而言之,volatile 的意思是“这个变量可能在程序外被修改”。
更详细地说,它意味着一个变量的值可以在没有任何相关指令的情况下改变。例如,在低级 I/O 中经常使用 volatile,其中寄存器或缓冲区的值可以由硬件设置。

1
在这种情况下似乎不适用。编译器没有编译InterlockedIncrement函数,并且将变量标记为volatile对函数外部没有影响。 - Suma
抱歉,我在阅读您的问题时可能跳过了一部分。 - jv42
这与告诉编译器不要优化对变量的访问有关,即使在函数内部也是如此。我不确定原型中为什么需要它,除了告诉您如何处理参数。 - jv42
@Suma,你说的“编译器没有编译函数”是什么意思?肯定有某个编译器在某个时刻编译过它吧? - n00bmind

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接