这是"*ptr ++ =*ptr + a"未定义的行为吗?

wha*_*cko 4 c c++ sequence-points

好吧,我真的不是真的需要这个答案,我只是好奇.

类似*ptr++ = a的表达式是完全有效的,因为我们操作两个对象ptr,*ptr但如果我写*ptr++ = *ptr + a它仍然有效?

例如,请考虑以下代码段:

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;
}
Run Code Online (Sandbox Code Playgroud)

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

int*_*nt3 12

结果*ptr++ = *ptr + a是未定义的.等号不是序列点,因此ptr在该语句中使用again 的值会导致未定义的行为.只要考虑结果,如果ptr在计算RHS表达式之前递增,并将其与在RHS表达式之后ptr递增的情况进行比较.

注意:这并不是说表达式的结果来自这两种情况中的任何一种.未定义未定义.

基本上,您只能指望两件事:在最后一个序列点和下一个序列点之间的某个时间评估后增量,并且表达式ptr++返回增量ptr 之前的值.所以*ptr++ = a很好,因为你可以指望结果ptr++.


Mar*_*ork 8

首先让我们假设'p'是指针类型.
否则所有操作都只是函数调用的语法糖.

让我们将声明分解为部分.

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)
Run Code Online (Sandbox Code Playgroud)

鉴于上述限制:
编译器可以通过多种方式重新排序这些指令,
但需要注意的是,(B)可能发生在(B)的唯一约束条件下它发生在(A)之后的任何地方. (D)中定义的p3可以是两个不同值中的一个,这取决于(B)的确切位置.

由于此处无法定义p3的值.
结果语句具有未定义的行为.