后缀增量何时生效

When does postfix increment take effect?

本文关键字:何时生 后缀      更新时间:2023-10-16

"C++Primer"(第5版)在第148页定义了后缀增量运算符:"后缀运算符将对象原始值的副本作为右值返回。"这对我来说很有意义。然而,在第149页,它带来了以下代码作为未定义行为的示例:

while (beg != s.end() && !isspace(*beg))
    *beg = toupper(*beg++);

它继续解释说,如果赋值的右边在左边之前求值,那么编译器会将上面的表达式求值为:

*(beg+1) = toupper(*beg)

对我来说,这与上述后缀增量运算符的定义相矛盾。也就是说,=只是一个运算符,所以整行*beg = toupper(*beg++)是一个表达式,所以beg的递增值的影响应该保持不变,在表达式被完全求值之前不起任何作用。那么,后缀增量何时生效的确切定义是什么呢?此外,在表达式中放置圆括号会影响这种情况的发生吗?


类似的问题出现在:后缀increment是否对返回值执行increment?。其中一条评论引用了以下关于序列点的讨论:未定义的行为和序列点。然而,我认为应该有一个简短而明确的定义:后缀增量何时生效?如果没有这样的定义,我会害怕在任何比标准*p++更复杂的表达式中使用后缀形式,而在表达式中没有p的其他用途。

正如您发布的第二个链接所述,这是序列点。所以,这个问题:

*beg = toupper(*beg++);

就是您不知道要首先评估哪个零件(请注意*运算符)。如果你不相信,请阅读这个答案。

您很好地理解后缀的概念,但您陷入了一个序列点。

此处增量发生在toupper赋值之前,因此过程为:*beg++;然后*beg=toupper(*beg-1);我写了*beg-1,因为*beg值增加了一,但它取了以前的值。