c – 所有全局变量是否易失性?

前端之家收集整理的这篇文章主要介绍了c – 所有全局变量是否易失性?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在这个例子中,正确性是否需要将global_value声明为volatile?
  1. int global_value = 0;
  2.  
  3. void foo () {
  4. ++ global_value;
  5. }
  6.  
  7. void bar () {
  8. some_function (++global_value);
  9. foo ();
  10. some_function (++global_value);
  11. }

我的理解是,对于pointers to mapped memory and variables which can be modified by signals来说,volatile是“意图”(并且强调不是线程安全的),但是很容易想象这个bar可能会编译成如下:

  1. push EAX
  2. mov EAX,global_value
  3. inc EAX
  4. push EAX
  5. call some_function
  6. call foo
  7. inc EAX
  8. push EAX
  9. call some_function
  10. mov global_value,EAX
  11. pop EAX

这显然是不正确的,但即使没有挥发性,我认为根据C抽象机是有效的.我错了还是有效?

如果是这样,在我看来,波动是常常被忽视的.这将是nothing new

扩展示例

  1. void baz (int* i) {
  2. some_function (++*i);
  3. foo ();
  4. some_function (++*i);
  5. }
  6.  
  7. int main () {
  8. baz (&global_value);
  9. }

即使bar被保证编译成一个正确的dont-cache-global_value实现,将会同样正确,还是允许缓存* i的非易失性值?

解决方法

不,在这里不需要volatile关键字.由于global_value在函数栏外可见,编译器不能假设如果调用另一个函数,则它将保持不变.

[更新2011-07-28]我发现一个很好的引文证明了这一切.它在ISO C99,5.1.2.3p2中,我太懒了,无法在这里复制.它说:

At certain specified points in the execution sequence called sequence points,all side effects of prevIoUs evaluations shall be complete and no side effects of subsequent evaluations shall have taken place.

序列点包括

>调用函数之后,对参数进行评估(6.5.2.2).
>完整表达式的结尾:[…]表达式语句中的表达式(6.8.3); […]

你有你的证明

猜你在找的C&C++相关文章