*p++ += 2是否定义良好?

16

我不确定下面的语句是否符合标准C的要求。

*p1++ += 2;

或其他类似声明:

*E1++ <operator>= E2

关于后缀自增运算符的标准C说明:

后缀++运算符的结果是操作数的值。 在获得结果之后,操作数的值会增加。(也就是说,适当类型的值1将被添加到它上面。)有关约束、类型和转换以及指针操作对操作的影响,请参见加法运算符和复合赋值的讨论。更新操作数存储的值的副作用应发生在前一个序列点和下一个序列点之间。

关于复合赋值:

形式为E1 op= E2的复合赋值与简单赋值表达式E1 = E1 op (E2)不同之处在于:左值E1只计算一次。


那么,是什么让你怀疑它可能是未定义的呢?对我来说,举个例子,一切看起来都很好,这让我很难开始回答这个问题:我不知道要关注什么。 - AnT stands with Russia
2
除非你已经研究过,否则不要在项目中编写这样的代码。 - wshcdr
9
为了把更多的代码放在一行上而写出这种难以辨认的代码是糟糕的编程。 :) (译者注:最后一个表情符号“:)”表示笑脸) - Almo
1
谁在乎呢?如果这段代码是真正的程序,它会立即被删除。实际上,它永远不应该通过代码审查并进入代码库。因此,它是否符合原始开发人员的预期并不重要,因为下一个看到它的开发人员不会立即理解它,从而将其重构出代码库。 - Martin York
1
如果有更广泛的背景,例如“我的程序在使用GCC和Visual C++编译时表现不同。我在其中发现了这行代码 - 这可能是问题所在吗?”那么这个问题就很相关。 - user23614
2个回答

23

我们稍微改写一下,以使它更加清晰:

(*p1++) += 2

因此,p1的旧值将被取消引用,并且2将被添加到其引用。并且在取消引用之后(或至少在等待取消引用的旧值加载之后),p1将被递增。这里没有问题:没有任何一块被使用多次。

话虽如此,您应该考虑重写代码以增加其清晰度:

*p1 += 2;
++p1;

9
“Then”这个词不太合适,因为+=的副作用可能会在++的副作用之前或之后发生。关键是它们作用于不同的标量对象。 - Cubbi

3
后缀递增运算符 (++) 返回操作数的值,即它给出一个r-value。 r-value 意味着它可以作为操作数放在赋值运算符 (=) 的左侧。
int i = 0;
i++ = 0   // [Error] lvalue required as left operand of assignment  

在某些情况下,

*p1++ += 2;  

后缀 ++ 不适用于 *p1,但是它适用于指针 p1++。这是因为后缀 ++ 的优先级高于解引用运算符 *。因此,编译器将解析上述语句为

*(p1++) += 2;

这段话表示:

  • 在将2加并将结果分配给它之前,必须评估*p1(以生成变量)。
  • 存储到*p1的结果必须在增量p1之前进行评估。
  • 一旦评估了*p1p1可以在任何时候递增。

在 C++ 中,最后一条语句是否保证执行? - BlueTrin
1
我本以为一旦p1被评估,就可以随时增加p1 - BlueTrin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接