spr*_*aff 11 c c++ global-variables qualifiers volatile
在这个例子中,是否需要global_value
声明正确性volatile
?
int global_value = 0;
void foo () {
++ global_value;
}
void bar () {
some_function (++global_value);
foo ();
some_function (++global_value);
}
Run Code Online (Sandbox Code Playgroud)
我的理解是volatile
" 指向 "用于指向映射内存和变量的指针,这些指针可以通过信号修改(并且强调不是为了线程安全)但是很容易想象bar
可能编译成这样的东西:
push EAX
mov EAX, global_value
inc EAX
push EAX
call some_function
call foo
inc EAX
push EAX
call some_function
mov global_value, EAX
pop EAX
Run Code Online (Sandbox Code Playgroud)
这显然是不正确的,但即使没有volatile
我认为根据C抽象机器它是有效的.我错了还是有效?
如果是这样的话,在我看来volatile
经常被忽视.这不是什么新鲜事!
void baz (int* i) {
some_function (++*i);
foo ();
some_function (++*i);
}
int main () {
baz (&global_value);
}
Run Code Online (Sandbox Code Playgroud)
即使bar
保证编译成正确的dont-cache-global_value实现,也baz
同样正确,还是允许缓存非易失性值*i
?
Rol*_*lig 10
不,volatile
这里不需要关键字.由于global_value
在函数外部是可见的bar
,因此如果调用另一个函数,编译器不能假定它保持不变.
[更新2011-07-28]我发现了一个很好的引用,证明了这一切.它是在ISO C99,5.1.2.3p2中,我太懒了,不能完全复制到这里.它说:
在称为序列点的执行序列中的某些特定点处,先前评估的所有副作用应该是完整的,并且不会发生后续评估的副作用.
序列点包括:
你有证明.
volatile
涉及longjmp
,信号处理程序,内存映射设备驱动程序以及编写自己的低级多线程同步原语的唯一用途.然而,对于最后一次使用volatile
是不够的,甚至可能不是必需的.你肯定还需要asm(或编译器特定的或C1x原子)来进行同步.
volatile
对于任何其他目的都没有用,包括您询问的代码.
归档时间: |
|
查看次数: |
5576 次 |
最近记录: |