首页 > 解决方案 > 在一个序列点,之前对 volatile 对象的所有访问都已稳定

问题描述

来自GNU文档volatile

最低要求是在一个序列点,所有先前对 volatile 对象的访问都已稳定,并且没有发生后续访问

好的,所以我们知道什么是序列点,现在我们知道 volatile 在 gcc 中相对于它们的行为。

所以,天真地我会看下面的程序:

volatile int x = 0;
int y = 0;

x = 1;    /* sequence point at the end of the assignment */
y = 1;    /* sequence point at the end of the assignment */
x = 2;    /* sequence point at the end of the assignment */

并将通过以下方式应用 GNU 要求:

在序列点(结束y=1)访问 volatile x = 1stable 并且没有x = 2发生子序列访问。

但这只是错误的,因为非易失性y = 1可以跨序列点重新排序,例如y = 1实际上可以在x = 1和之前执行x = 2,而且它可以被优化掉(不违反 as-if 规则)。

所以我很想知道如何正确应用 GNU 要求,我的理解有问题吗?要求写错了吗?

也许应该将要求写成如下形式:

最低要求是在具有副作用的序列点上,所有先前对易失性对象的访问都已稳定,并且没有发生后续访问

或者正如评论中优雅地建议的那样:

最低要求是在一个序列点,所有UNSEQUENCED先前对 volatile 对象的访问都已稳定,并且没有发生后续访问

所以我们只能x = 1;将它应用到 end of和 end of的序列点x = 2;上,这绝对是真的,之前对 volatile 对象的访问已经稳定并且没有发生后续访问?

标签: cgcclanguage-lawyervolatilesequence-points

解决方案


推荐阅读