我似乎对volatiles
有一个合理的理解,但是有一个看似模糊的情况,我不确定按照标准应该如何工作。 我已经阅读了C99的相关部分以及关于SO的十几个或更多相关post,但是在这种情况下找不到逻辑或者解释这个案例的地方。
假设我们有这段代码:
int a, c; volatile int b; a = b = 1; c = b += 1; /* or equivalently c = ++b; */
应该像这样评估:
b = 1; a = b; // volatile is read
或者像这样:
b = 1; a = 1; // volatile isn't read
?
同样,应该像这样评估:
int tmp = b; tmp++; b = tmp; c = b; // volatile is read
或者像这样:
int tmp = b; tmp++; b = tmp; c = tmp; // volatile isn't read
?
在简单的情况下,如a = b; c = b;
a = b; c = b;
事情很清楚。 但是上面那些怎么样?
基本上,问题是,当对象是易变的时,“表达式具有赋值后左操作数的值”究竟在C99的6.5.16c3中意味着什么?:
赋值运算符将值存储在左操作数指定的对象中。 赋值表达式在赋值后具有左操作数的值 ,但不是左值。
它是否意味着额外读取volatile以生成赋值表达式的值?
更新 :
所以,这就是困境。
如果没有从易失性对象的额外读取中获得“赋值后的对象的值”,则编译器假设易失性对象b
:
而且由于所有这些,表达式值,如果不是从易失性对象的额外读取中获得的,则不会产生易失性对象的值,标准声称应该是这种情况。
这两种假设似乎都不符合易失性物体的性质。
如果OTOH,“赋值后对象的值”是从所述易失性对象的额外隐含读取中获得的,那么使用易失性左操作数评估赋值表达式的副作用取决于表达式值是否被使用或者是完全随意,这将是一个奇怪的,意外的和记录不良的行为。
C11澄清这是未定义的。
你可以在这里找到C11的最终草案。 你引用的第二句现在提到脚注111:
赋值运算符将值存储在左操作数指定的对象中。 赋值表达式具有赋值后的左操作数的值, 111)但不是左值。
脚注111说:
111)允许实现读取对象以确定值但不需要,即使对象具有volatile限定类型。
以上就是c/c++开发分享赋值表达式和volatile相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/559773.html