关于volatile语义及Sequenced before关联的疑问与代码问询
关于C标准中Sequenced before与
volatile的问题解答 先明确问题涉及的代码示例:
void foo(volatile int* a, int *b, volatile int *c){ *a = 1; *b = 2; *c = 3; }
结合C标准5.1.2.3的相关定义,对两个问题解答如下:
问题1:*a = 1; 是否Sequenced before *c = 3;?
是。
原因:根据C标准5.1.2.3的定义,抽象机必须按语义规定执行所有带“所需副作用”的表达式,而对volatile对象的访问属于明确的副作用,编译器不能省略或乱序这类操作。同时,Sequenced before是单线程中求值操作的偏序关系,代码中语句按顺序书写,*a = 1作为完整表达式,其所有求值(包括对volatile对象的赋值副作用)会被Sequenced before后续的*c = 3的求值及副作用,抽象机中这两个操作的顺序严格遵循代码书写顺序。
问题2:*a = 1; 是否Sequenced before *b = 2;?
是。
原因:在单线程的抽象机语义中,相邻的完整表达式(这里每个赋值语句都是独立的完整表达式)之间存在Sequenced before关系——前一个完整表达式的所有求值和副作用,都会被排在后一个完整表达式的求值之前。虽然*b是非volatile对象,但*b = 2存在修改内存对象的副作用,编译器无法推断该副作用是不需要的,因此必须按抽象机的顺序执行。也就是说,在标准定义的抽象模型里,*a = 1的执行必然先于*b = 2。
相关标准引用
在抽象机中,所有表达式均按照语义规定进行求值。若实际实现可推断某表达式部分的值未被使用,且不会产生所需副作用(包括调用函数或通过volatile访问对象导致的副作用),则无需对该部分表达式求值。
Sequenced before是单线程中执行的求值操作之间的一种非对称、传递的两两关系,它在这些求值操作之间引入了偏序。
内容的提问来源于stack exchange,提问作者Some Name
相关产品推荐
相关产品推荐

