序列点间能否多次读取volatile变量?C11标准合规性问询
关于表达式
x = volatile_var - (volatile_var + volatile_var)的C11标准判定 首先明确结论:该表达式不属于未定义行为,严格遵循C11标准的判定结果是:行为属于未指定行为——编译器必须执行全部三次对volatile_var的读取操作,但读取顺序由编译器自行决定;若volatile_var的值在多次读取间被外部修改,最终计算结果可能不同,但整个表达式的执行不会触发未定义行为。
结合C11标准条款具体分析:
- 6.7.3p7:要求编译器必须严格执行对volatile对象的每一次读取,不能因优化省略任何一次读操作。因此这个表达式里的三次
volatile_var读取都会被执行,不会被合并或优化掉。 - 6.5p3:规定序列点之间的子表达式求值顺序未指定。在这个赋值表达式中,三个
volatile_var的读取操作都处于同一个序列点(语句结束的序列点)之前,它们的求值顺序由编译器自由选择(比如先读第一个,再读第二个,最后读第三个;或者其他任意顺序),但这属于“未指定行为”,而非未定义行为。 - 6.5p2:指出未排序的副作用会导致未定义行为,但这里的副作用是对
volatile_var的读取(根据C11 5.1.2.3p2,对volatile对象的读取属于副作用)。由于这些副作用都是读取操作,不会修改volatile_var的值,即使顺序未指定也不会产生冲突——只有当存在对同一对象的写操作,且写操作与读/写操作未排序时,才会触发未定义行为。
内容的提问来源于stack exchange,提问作者Elzaidir
相关产品推荐
相关产品推荐

