后缀增量何时生效
When does postfix increment take effect?
"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值增加了一,但它取了以前的值。
相关文章:
- 何时在引用或唯一指针上使用移动语义
- 增量运算符与后缀混淆
- 何时提供默认参数作为模板参数
- C++-明确何时以及如何调用析构函数
- 在以唯一ptr为值的C++映射中,动态内存何时会被销毁
- 何时应通过引用传递矢量参数而不是按值传递矢量参数?
- 如何在OpenSSL库的名称中添加后缀'd'?
- 如果非动态变量被指针引用,何时超出范围?
- 类作用域的类型别名"using":[何时]方法中的用法可以先于类型别名?
- 何时定义QT_NO_CONTEXTMENU?
- 何时为派生类初始化 vptr?
- C++17 十六进制浮点文字单精度后缀冲突?
- 如何知道何时调用删除以及何时调用 delete[] C++?
- 指针的 C++ 动态数组 - 何时需要使用它?
- 我应该在 C++ 中何时/为什么使用 STATIC?
- 变量的值何时可以在C++中意外更改?
- 使用带有链表的堆栈数据结构将中缀转换为后缀
- 调用方如何知道 VARIANT 中何时有十进制?
- TCP插座需要何时需要保持贴生
- 后缀增量何时生效