序列点和副作用

sequence point and side effects

根据序列点的定义,序列点是“执行序列中的指定点称为序列点,保证之前评估的所有副作用是完整的

所以在下面的程序中,++ 运算符的所有副作用必须在进入 && 运算符的第二部分之前执行,即 i 应该递增到 1因为 && 是一个序列点。

#include<stdio.h>

int main()
{
    int i=0,a;
    a=i++&&1;
    printf("%d",a);
    getchar();
    return 0;
}

预期输出:

1 (1&&1=1)

实际输出:

0

为什么 i 在第二部分之前不递增?

使用三元运算符也给出相同的输出:

#include<stdio.h>

int main()
{
    int i=0,a;
    a=(i++)?1:0;

    printf("%d",a);
    getchar();
    return 0;
}

三元运算符也是一个序列点。那么这不应该给出输出 1 而不是 0 吗?

i++

计算为 i 的先前值。

因为 i 的副作用值增加了 1

所以是的,序列点在那里,但表达式 i++ 的计算结果为 0(尽管 i 的值同时为 1

对于预期的结果use ++i instead of i++

来自 6.5.2.4 C11 规范中的后缀递增和递减运算符

The result of the postfix ++ operator is the value of the operand. As a side effect, the value of the operand object is incremented (that is, the value 1 of the appropriate type is added to it). See the discussions of additive operators and compound assignment for information on constraints, types, and conversions and the effects of operations on pointers. The value computation of the result is sequenced before the side effect of updating the stored value of the operand. With respect to an indeterminately-sequenced function call, the operation of postfix ++ is a single evaluation. Postfix ++ on an object with atomic type is a read-modify-write operation with memory_order_seq_cst memory order semantics.98)

98) Where a pointer to an atomic object can be formed and E has integer type, E++ is equivalent to the following code sequence where T is the type of E:

T *addr = &E;
T old = *addr;
T new;
do {
  new = old + 1;
} while (!atomic_compare_exchange_strong(addr, &old, new));

with old being the result of the operation. Special care must be taken if E has floating type; see 6.5.16.2.)