微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么(* p = * p)&(* q = * q);在C中触发未定义的行为

为什么(* p = * p)& (* Q = * Q);如果p和q相等,则在C中触发未定义的行为.
int f2(int * p,int * q)
{
  (*p=*p) & (*q=*q);
  *p = 1;
  *q = 2;
  return *p + *q;
}

来源(顺便说一句好文章):http://blog.frama-c.com/index.php?post/2012/07/25/On-the-redundancy-of-C99-s-restrict

解决方法

C11标准对该声明的裁决
(*p=*p) & (*q=*q);

是:

P1

§6.5p3

The grouping of operators and operands is indicated by the Syntax. 85) Except as specified later,side effects and value computations of subexpressions are unsequenced.

由于§6.5.10BitwiseAND运算符未提及其操作数的排序,因此(* p = * p)和(* q = * q)未被排序.

P2

§6.5p2

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)

两个赋值(* p = * p)和(* q = * q)都没有序列w.r.t.相互§6.5p3,如果p == q,则对同一个对象产生副作用.因此,那么通过§6.5p2我们有UB.

P3

§3.4.3

undefined behavIoUr

behavior,upon use of a nonportable or erroneous program construct or of erroneous data,for which this International Standard imposes no requirements.

根据这一条款,我们知道该标准对UB没有任何要求.这通常被编译器解释为忽略发生此类行为的可能性的许可.

特别是,它允许编译器不处理情况p == q,这意味着它可以假设p!= q.

P1 P2 P3 – > C1

因为组合的前提P1,P2和P3可以假设(* p = * p)和(* q = * q)不调用UB,所以也可以假设它们是加载并存储到不同的存储位置.这也意味着f2的返回值必须为3而不是4.如果p == q,则标准不对发生的情况施加任何要求.

原文地址:https://www.jb51.cc/c/114008.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐