为什么++++i常规但i++++在C++中不规则

why ++++i regular but i++++ not regular in C++?

本文关键字:C++ 不规则 i++++ ++++i 常规 为什么      更新时间:2023-10-16

当我使用i++++时给出编译错误:

for (int i=1;i<=10;i++++) {} //a.cpp:63: error: lvalue required as increment operand

int i = 0;
i++++; // a.cpp:65: error: lvalue required as increment operand

但是当我使用时++++i正在工作。有人解释我为什么++++i规律但i++++不规律?

谢谢。

由于x类型是内置的基元类型,因此这两个表达式都调用未定义的行为,因为两者都尝试在两个序列点之间修改同一对象两次。

不要做其中任何一个。

阅读此常见问题解答 :

未定义的行为和序列点


但是,如果x类型是用户定义类型,并且您已经为两个表达式重载了operator++,则两者都是明确定义的

为此,请参阅本主题以了解说明和详细信息:

未定义的行为和重新加载的序列点

C++标准在第 5.2.6 节中说 i++ 的结果是可修改的左值,而在 5.3.2 中,++i 的结果是可修改的左值。 这有助于解释为什么 i++++ 和 ++++i 不需要生成诊断,并且有时看起来可以工作。

但是,++++i 在上一个和下一个序列点之间修改 i 两次,因此结果仍然是未定义的行为。 ++++i 被允许工作,但不必这样做。

幸运的是,您的编译器诊断为 i++++。

因为运算符的概念"签名"是:

​T& operator ++(T& a);​     // pre
​T operator ++(T& a, int);​ // post
                          // note the int is solely to distinguish the two

一个返回引用(左值),另一个不返回。然而,两者都将引用作为它们的参数,因此返回引用(++i)的可以链接,而不返回引用(i++

的不能。

请注意,正如@Nawaz所说,有效的行为会调用未定义的行为,就像在假设中不起作用的行为一样,即使它确实如此。

正如一些人所说,编译器接受++++i,但是当它被评估时,它会在 C++03 中产生未定义的行为。

请注意,简单地说sizeof(++++i)就可以了,因为不会评估任何内容。说++++i在 C++11 中是可以的,即使它被评估了。

从"你想做什么"的角度来回答这个问题:一开始调用i++++是没有意义的,因为i++不会返回对递增的i变量的引用,而是返回i递增之前的值。所以i++++基本上会这样做:

  1. i复制到临时变量t
  2. 递增i
  3. t复制到临时变量u
  4. 递增t
  5. 扔掉tu

所以剩下的就是i的一个增量.

另一方面,++++i只是简单地

  1. 增量i
  2. 再次递增i

这确实很有用,不是在整数类型中,而是当i是非随机访问迭代器时,因为那样你就不能依赖i+=2