这是“* ptr ++ = * ptr + a”未定义行为? [英] Is this "*ptr++ = *ptr + a" undefined behavior?

查看:160
本文介绍了这是“* ptr ++ = * ptr + a”未定义行为?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

表达式像 * ptr ++ = a 是完全有效的,因为我们对两个对象操作 ptr * ptr * ptr ++ = * ptr + a 是否仍然有效?

Expressions like *ptr++ = a are perfectly valid since we are operating on two objects ptr and *ptr but if i write *ptr++ = *ptr + a is it still valid ?

例如,考虑以下片段:

int main(void){
   int a[] = {5,7,8,9,2};

   int* p =a;

   *p++ = 76; /*altering the first element */
   *p++ = *p + 32; /*altering the second element */    

   p = a;
   int i;
   for(i = 0;i<5; i++)
      printf("%d ",*p++);

   return 0;
}



我认为没有什么可担心的表达式 * p ++ = * p + 32; 但我不确定所涉及的序列点。

I think that there is nothing to worry about with the expression *p++ = *p + 32; but I am unsure about the sequence points involved.

推荐答案

首先让我们假设'p'是一个指针类型。

否则所有的操作

First let us assume that 'p' is a pointer type.
Otherwise all the operation are just syntactic sugar for function calls.

Lets us break the statement down into parts.

code> int * p = a;

* p ++ = * p + 32;

<<序列点>>
//第1部分:p ++
//注意标准中post增量的定义是(5.2.6)
//表达式p ++的结果是'p'而由p表示的
//对象的值增加。这可以用伪代码表示为:
(A)int * p1 = p;
(B)p = p + 1;

//第2部分:* p(第1部分的结果)(On * p ++)
(C)int& p2 = * p1; //注意使用p1;

//第3部分:* p(On * p + 32)
//注意:在第1部分中使用'p'和'p' 2
(D)int& p3 = * p;

//第4部分:* p + 32;
(E)int p5 = p3 + 32; //注意使用p3;

//第5部分:作业。
(F)p2 = p5;
<<序列点>>

必须保存的订单:
(A)之前(B)
(A)之前(C)
(D)之前b(C)之前(F)
(E)之前(F)

int* p = a; *p++ = *p + 32; << Sequence Point >> // Part 1: p++ // Note the definition of post increment in the standard is (5.2.6) // The result of the expression p++ is the value of 'p' while the value of the // objects represented by 'p' is incremented. This can be represented in pseudo code as: (A) int* p1 = p; (B) p = p + 1; // Part 2: *p (On the result of Part 1) (On *p++) (C) int& p2 = *p1; // Note the use of p1; // Part 3: *p (On *p + 32) // Note: There is no linkage between this use of 'p' and the 'p' in Part 1&2 (D) int& p3 = *p; // Part 4: *p + 32; (E) int p5 = p3 + 32; // Note the use of p3; // Part 5: Assignment. (F) p2 = p5; << Sequence Point >> Ordering that must be preserved: (A) Before (B) (A) Before (C) (D) Before (E) (C) Before (F) (E) Before (F)



<上面的约束:

编译器可以用几种方式重新排序这些指令,

但是要注意的是,(B)可以发生在(B)上的唯一约束的任何地方,是在(A)之后发生的。因此,根据(B)的确切位置,(D)中定义的p3的值可以是两个不同的值之一。

Given the above constraints:
The compiler can re-order those instructions in several ways,
But the main point to note is that (B) can happen anywhere the only constraint on (B) is that it happen after (A) Thus the value of p3 as defined in (D) could be one of two different values depending on the exact position of (B).

由于p3的值不能在这里定义。

生成的语句具有未定义的行为。

As the value of p3 can not be defined here.
The resulting statement has undefined behavior.

这篇关于这是“* ptr ++ = * ptr + a”未定义行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆