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吗?
i++
Run Code Online (Sandbox Code Playgroud)
评估以前的值i.
随着副作用值i增加1.
所以是的,序列点在那里,但表达式的i++计算结果是0(虽然值i是1在同一时间)
对于预期的结果使用++i而不是i++.
从6.5.2.4 C11规范中的Postfix增量和减量运算符:
postfix ++运算符的结果是操作数的值.作为副作用,操作数对象的值递增(即,将相应类型的值1添加到其中).有关约束,类型和转换以及操作对指针的影响的信息,请参阅加法运算符和复合赋值的讨论.在更新操作数的存储值的副作用之前,对结果的值计算进行排序.对于不确定顺序的函数调用,后缀++的操作是单个评估.具有原子类型的对象上的Postfix ++是具有memory_order_seq_cst内存顺序语义的读取 - 修改 - 写入操作.98)
98)如果可以形成指向原子对象的指针而E具有整数类型,则E ++等效于以下代码序列,其中T是E的类型:
Run Code Online (Sandbox Code Playgroud)T *addr = &E; T old = *addr; T new; do { new = old + 1; } while (!atomic_compare_exchange_strong(addr, &old, new));旧的是操作的结果.如果E有浮动型,必须特别小心; 见6.5.16.2.)