序列点和副作用

cod*_*luv 2 c sequence-points post-increment

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

因此,在下面的程序中,++操作符的所有副作用必须在进入&&操作符的第二部分之前执行,即,i应该像&&序列点一样递增到1 .

#include<stdio.h>

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

预期产量:

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;
}
Run Code Online (Sandbox Code Playgroud)

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

Moh*_*ain 5

i++
Run Code Online (Sandbox Code Playgroud)

评估以前的值i.

随着副作用值i增加1.

所以是的,序列点在那里,但表达式的i++计算结果是0(虽然值i1在同一时间)

对于预期的结果使用++i而不是i++.

6.5.2.4 C11规范中的Postfix增量和减量运算符:

postfix ++运算符的结果是操作数的值.作为副作用,操作数对象的值递增(即,将相应类型的值1添加到其中).有关约束,类型和转换以及操作对指针的影响的信息,请参阅加法运算符和复合赋值的讨论.在更新操作数的存储值的副作用之前,对结果的值计算进行排序.对于不确定顺序的函数调用,后缀++的操作是单个评估.具有原子类型的对象上的Postfix ++是具有memory_order_seq_cst内存顺序语义的读取 - 修改 - 写入操作.98)

98)如果可以形成指向原子对象的指针而E具有整数类型,则E ++等效于以下代码序列,其中T是E的类型:

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

旧的是操作的结果.如果E有浮动型,必须特别小心; 见6.5.16.2.)