c - 序列点和副作用 : Quiet change in C11?

标签 c c99 undefined-behavior c11 sequence-points

C99 §6.5 表达式

(1) An expression is a sequence of operators and operands that specifies computation of a value, or that designates an object or a function, or that generates side effects, or that performs a combination thereof.

(2) Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression.72) Furthermore, the prior value shall be read only to determine the value to be stored.73)

带脚注

72) A floating-point status flag is not an object and can be set more than once within an expression.

73) This paragraph renders undefined statement expressions such as

    i = ++i + 1;
    a[i++] = i;

while allowing

    i = i + 1;
    a[i] = i;

其中 C11 §6.5 更改为((1) 的文本有附录):

(1) […] The value computations of the operands of an operator are sequenced before the value computation of the result of the operator.

(2) If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined. If there are multiple allowable orderings of the subexpressions of an expression, the behavior is undefined if such an unsequenced side effect occurs in any of the orderings.84)

其中 C11 中的脚注 84 与 C99 中的脚注 73 相同。

我有点困惑……我将 C11 (2) 读为“[……](对同一标量对象的不同副作用)或(使用同一标量对象的值的值计算)[……] "这似乎甚至不允许 foo =++i (有一个副作用,我们根据更改的对象使用一个值)。不过,我不是母语人士,所以如果有人能告诉我应该如何“解析”这句话就好了。 C99我看得懂,但C11的写法我不是很懂。

无论如何,真正的问题是:这是从 C99 到 C11 的变化,还是这些措辞等同?如果是这样,为什么它被改变了?如果不是,有人可以举例说明在 C99 中是 UB 而在 C11 中不是,反之亦然吗?

最佳答案

C11(以及 C++11)完全修改了排序的措辞,因为 C11 现在有了线程,它必须解释访问相同数据的线程之间的排序意味着什么。委员会的目的是在只有一个执行线程的情况下保持与 C99 的向后兼容。

让我们看一下C99版本:

  1. Between the previous and next sequence point

  2. an object

  3. shall have

  4. its stored value modified at most once

  5. by the evaluation of an expression.

与新文本相比

If a side effect on

4的不同术语,修改存储值

a scalar object

对2中之前措辞的限制,新的文字只说 关于标量对象的一些东西

is unsequenced relative to either

unsequenced 是 1 中概念的概括。这两个语句 由一个序列点分开。想想两个修改的线程 相同的数据而不使用锁或类似的东西。

a different side effect on the same scalar object

对象只允许修改一次

or a value computation using the value of the same scalar object,

或者值的读取可能不会与修改同时出现

the behavior is undefined.

3. 中的“shall”是含蓄地说的。如果 他们没有实现。

关于c - 序列点和副作用 : Quiet change in C11?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21066593/

相关文章:

c++ - 类中声明的枚举的默认值

C多线程死锁的线程事件

c - 链表 append 实现在 C 中更新所有节点值

gcc - 如何使用 GCC 编译一个独立的环境?

c++ - 同一地址的变量如何产生 2 个不同的值?

c++ - 如何处理 clang 的 (3.9) -Wexpansion-to-defined 警告?

objective-c - 给矩形添加颜色

c - 幂函数 K&R

c - C语言的分布式算法

C99:为什么我的字符串改变了?