“C ++ Primer”(第5版)(第148页)定义了后缀增量运算符:“后缀运算符将对象原始值的副本作为右值返回。”这对我来说很有意义。但是,在页149,它将以下代码作为未定义行为的示例:
while (beg != s.end() && !isspace(*beg))
*beg = toupper(*beg++);
它继续解释说,如果在左侧之前评估赋值的右侧,那么编译器会将上面的表达式计算为:
*(beg+1) = toupper(*beg)
对我而言,这与后缀增量运算符的上述定义相矛盾。也就是说,=
只是一个运算符,因此整行*beg = toupper(*beg++)
是一个表达式,因此应该保持beg
递增值的效果,并且在表达式之前不会产生任何影响。完全评估。那么,后缀增量何时生效的准确定义是什么?此外,在表达式中放置括号是否会影响何时发生?
类似的问题出现在:Does postfix increment perform increment not on returned value?。其中一条评论引用了以下关于序列点的讨论:Undefined behavior and sequence points。但是,我认为应该有一个简短明确的定义:后缀增量何时生效?如果没有这样的定义,我会害怕在任何比标准*p++
更复杂的表达式中使用后缀形式,而在表达式中没有使用p
。
答案 0 :(得分:0)
作为您发布状态的第二个链接,这是一个 序列点 。所以,这个问题:
*beg = toupper(*beg++);
是您不知道将首先评估哪个部分(请注意*
运算符)。如果您不相信,请阅读此answer。
您完全理解 postfix 概念,但是你在序列点上纠缠不清。
答案 1 :(得分:0)
此处增量发生在toupper赋值之前,因此进程是:
*beg++;
然后*beg=toupper(*beg-1);
我写了* beg-1因为* beg值增加了1,但它需要先前的值。