为什么"volatileQualifiedExpr + volatileQualifiedExpr"不一定是C中的UB而是C++中的UB?

Joh*_*itb 11 c c++ side-effects volatile

当我今天阅读C标准时,它说的是副作用

访问易失性对象,修改对象,修改文件或调用执行任何这些操作的函数都是副作用

和C++标准说

访问由volatile glvalue(3.10)指定的对象,修改对象,调用库I/O函数或调用执行任何这些操作的函数都是副作用

因此,因为禁止在同一个标​​量对象上发生无序的副作用,C允许以下内容,但C++使其未定义行为

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

int b = *pa + *pa;
Run Code Online (Sandbox Code Playgroud)

我正确地阅读了规格吗?如果出现差异,原因是什么?

edA*_*a-y 1

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

\n\n

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

\n\n
\n

\xe2\x80\x94 在序列点,易失性对象是稳定的,因为之前的访问已完成且后续访问尚未发生。

\n
\n\n

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

\n\n

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

\n

  • 抱歉,我不明白这个答案。 (2认同)