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

前端之家收集整理的这篇文章主要介绍了为什么(* 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.f2er.com/c/114008.html

猜你在找的C&C++相关文章