Tag: 易变

什么时候可以完全优化易失性变量?

考虑以下代码示例: int main(void) { volatile int a; static volatile int b; volatile int c; c = 20; static volatile int d; d = 30; volatile int e = 40; static volatile int f = 50; return 0; } 没有volatile ,编译器可以优化掉所有变量,因为它们永远不会被读取。 我认为a和b可以被优化掉,因为它们是完全未使用的,请参见未使用的volatile变量 。 我认为c和d因为被写入而无法删除,并且必须实际发生对volatile变量的写入。 e应该相当于c 。 GCC不会优化f ,但它也不会发出任何写入指令。 在数据部分中设置50。 LLVM(clang)完全删除f 。 这些陈述是真的吗? 如果永远不会访问volatile变量,则可以将其优化掉。 静态或全局变量的初始化不计为访问。

指针指向非易失性对象的指针行为的要求

C11 6.7.3类型限定词,第7段,内容如下: 具有volatile限定类型的对象可能以实现未知的方式进行修改,或者具有其他未知的副作用。 因此,任何涉及这种对象的表达都应严格按照抽象机的规则进行评估,如5.1.2.3所述。 在以下示例中,第三行中访问的对象是否受上述规则约束? int x; volatile int *p = &x; *p = 42; 换句话说,lvalue *p具有类型volatile int的事实是否意味着正在访问volatile对象,或者p指向非易失性对象x的事实意味着编译器可以使用此知识进行优化并省略不稳定的访问? 由于它可能是有意义的,我感兴趣的特定用例不在普通C的范围内; 它涉及使用pre-C11结构(可以是内联asm或简称为黑盒子)进行线程同步的primefaces,用于primefaces比较和交换,具有以下习语: do { tmp = *p; new = f(tmp); } while (atomic_cas(p, tmp, new) != success); 这里指针p类型为volatile int * ,但是我关注当实际指向的对象是非易失性时会发生什么,特别是编译器是否可以*p tmp = *p的单个访问转换为两个访问以下forms: do { new = f(*p); } while (atomic_cas(p, *p, new) != success); 这显然会导致代码不正确。 […]