假设我有一个这样的结构:
volatile struct { int foo; int bar; } data;
data.foo = 1;
data.bar = 2;
data.foo = 3;
data.bar = 4;
作业都保证不被重新排序吗?
例如,如果没有 volatile,编译器显然可以将其优化为不同顺序的两条指令,如下所示:
data.bar = 4;
data.foo = 3;
但是对于 volatile,编译器是否需要不做这样的事情?
data.foo = 1;
data.foo = 3;
data.bar = 2;
data.bar = 4;
(将成员视为单独的不相关的易失性实体 - 并进行重新排序,我可以想象它可能会尝试改善引用的局部性,以防万一foo and bar位于页面边界 - 例如。)
另外,答案对于 C 和 C++ 标准的当前版本是否一致?
c /questions/tagged/c
它们不会被重新排序。
C17 6.5.2.3(3) 说:
后缀表达式后跟 .运算符和标识符指定结构的成员
或联合对象。该值是指定成员的值,97),并且如果第一个表达式是左值
左值。如果第一个表达式具有限定类型,则结果具有该类型的限定版本
指定成员的。
Since data
has volatile
-限定类型,也是如此data.bar
and data.foo
。因此,您正在执行两项任务volatile int
对象。并通过 6.7.3 脚注 136,
对如此声明的对象的操作[如volatile
] 不得被“优化”
除非计算表达式的规则允许,否则执行或重新排序。
一个更微妙的问题是编译器是否可以使用一条指令将它们分配给它们,例如,如果它们是连续的 32 位值,它是否可以使用 64 位存储来设置两者?我认为不会,至少 GCC 和 Clang 不会尝试这样做。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)