为什么“VolatileQualifiedExpr + VolatileQualifiedExpr”在C中不一定是UB,而在C++中却不一定是UB?

2023-12-22

当我今天读 C 标准时,它提到了副作用

访问易失性对象、修改对象、修改文件或调用函数 这些操作中的任何一个都是副作用

C++ 标准说

访问由易失性泛左值 (3.10) 指定的对象、修改对象、调用库 I/O 函数或调用执行任何这些操作的函数都是副作用

因此,因为两者都禁止在同一标量对象上发生未排序的副作用,所以 C 允许以下行为,但 C++ 使其成为未定义的行为

int a = 0;
volatile int *pa = &a;

int b = *pa + *pa;

我是否正确阅读了规格?如果有的话,造成差异的原因是什么?


我不认为 C 和 C++ 在这方面存在有效的差异。尽管排序的措辞有所不同,但最终结果是相同的:两者都会导致未定义的行为(尽管 C 似乎表明评估将成功,但结果未定义)。

在 C99 中(抱歉,手边没有 C11)第 5.1.2.3.5 段指定:

— 在序列点,易失性对象是稳定的,因为之前的访问是稳定的 完整的和后续的访问尚未发生。

结合 5.1.2.3.2 中的报价将表明以下值pa至少有一次访问不会处于稳定状态pa。这在逻辑上是有意义的,因为编译器可以以任何顺序评估它们,一次或同时(如果可能的话)。它实际上并没有定义什么stable意思是然而。

在 C++11 中,1.9.13 明确引用了无序操作。然后点 15 表示对同一操作数的此类无序操作未定义。自从未定义的行为可能意味着任何事情都会发生它也许比C强unstable行为。然而,在这两种情况下,都不能保证你的表达结果。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么“VolatileQualifiedExpr + VolatileQualifiedExpr”在C中不一定是UB,而在C++中却不一定是UB? 的相关文章

随机推荐