sequence point顺序点,side effect副作用

In C99  --- 6.5 Expressions

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

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

3. The grouping of operators and operands is indicated by the syntax. Except as specified later (for the function-call (), &&, ||, ?:, and comma operators),the order of evaluation of subexpressions and the order in which side effects take place are both unspecified

In C++ ISO/IEC 14882:2003 --- 5 Expressions

4. Except where noted, the order of evaluation of operands of individual operators and subexpressions of individual expressions,and the order in which side effects take place, is unspecified.53) Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored.The requirements of this paragraph shall be met for each allowable ordering of the subexpressions of a full expression; otherwise the behavior is undefined.

So undefined:

i = v[i++];

i = ++i + 1;

a[i] = i++;

while allowing

i = i + 1;

a[i] = i;

注意这句话

2) Furthermore, the prior value shall be accessed only to determine the value to be stored.

就是说只有用来仅是直接决定 要存的值得时候,才可以取,像上面的例子a[i] = i,    i = i+1这两个→ →的i都只是仅仅用来决定左值的,所以没问题

而上面两个i++了,是不行的,对i做了改变,看似也是决定了左值的,但是有问题就是对i进行了修改,不能修改两次及以上,参考第一条

1) Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression.

 

参考

http://c-faq.com/expr/seqpoints.html

 if an object is written to within a full expression, any and all accesses to it within the same expression must be directly involved in the computation of the value to be written. This rule effectively constrains legal expressions to those in which the accesses demonstrably precede the modification. For example, the old standby i = i + 1 is allowed, because the access of i is used to determine i's final value. The example

	a[i] = i++

is disallowed because one of the accesses of i (the one in a[i]) has nothing to do with the value which ends up being stored in i (which happens over in i++), and so there's no good way to define--either for our understanding or the compiler's--whether the access should take place before or after the incremented value is stored. Since there's no good way to define it, the Standard declares that it is undefined, and that portable programs simply must not use such constructs.

http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points

http://en.wikipedia.org/wiki/Sequence_point

 

此外

i=i++;显然就属于这种情况,如果i这里是基本类型的话。而在c.erase(i++)就是另外一种

情况,因为在i++之后调用c.erase之前是有一个时序点的。因此就没有二义性问题。

 

这里面举了个函数调用sequence point的例子

 

 

再次

gcc 中-Wsequence-point会给warning的

比如

#include <stdlib.h>

int main()
{
        int x = 0;
        x += x>0?x++:x--;
        x = x+1;
        x = x++;
        int a[10];
        a[x] = x;
        return 0;
}
a.c:6: warning: operation on ‘x’ may be undefined
a.c:8: warning: operation on ‘x’ may be undefined

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值