2011-05-13 59 views
4

当我使用i++++给予编译错误:为什么++++我常规,但我++++不规则在C + +?

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++++不正常?

谢谢。

+1

IT BUUURNSSS !!! – 2011-05-13 05:11:44

+0

为什么不使用“+ =”? – jveazey 2011-05-13 05:12:19

+0

@John - 不完全。 – 2011-05-13 05:18:08

回答

13

由于x类型是内置的原语类型,两个表达式调用未定义行为,因为两者试图修改相同对象两次2个序列点之间。

不要做任何一个。

阅读FAQ:

Undefined behavior and sequence points


但是如果x类型是用户定义的类型,你已经为两个表达式重载operator++,然后双方将良好定义为

对于这一点,看到这个题目就知道了解释和详细信息:

Undefined behavior and sequence points reloaded

+0

等一下,为什么预先增加一个UB? – Xeo 2011-05-13 05:14:02

+0

@Xeo:都试图在两个序列点之间修改对象两次 – Nawaz 2011-05-13 05:15:14

+0

不是'++++ x'实现为'x.operator ++()。operator ++()'并且不是UB? – Xeo 2011-05-13 05:16:32

5

由于运营商的概念 “签名” 是:

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

一个返回引用(左值),另一个没有。然而,两者都以参考为参数,所以返回参考文献(++i)的参考文献可以链接,而不参考的文章(i++)不能。

请注意,如@Nawaz所述,工作调用未定义的行为,就像那个在假设中不工作的调用未定义的行为一样。

+0

问题中的*类型*是内置类型。所以'operator ++'不会出现在图片中。 – Nawaz 2011-05-13 05:23:30

+0

没有,见5.2.6。 – 2011-05-13 05:24:07

+0

@Nawaz - 我用它来说明。我知道内置类型不会使用'operator ++'作为任何东西,但看到签名有助于理解问题。 – 2011-05-13 23:43:43

6

C++标准在5.2.6节中说i ++的结果是一个可修改的左值,在5.3.2中++ i的结果是一个可修改的左值。这可以帮助解释为什么我不需要生成诊断程序,并且有时可能看起来有效。

但是,++++我在前一个和下一个序列点之间修改了两次,所以结果仍然是未定义的行为。 ++++我被允许工作,但它不必。

幸运的是,你的编译器诊断出我++++。

+0

因为我只能访问C++ 0x FDIS,所以这个改变了吗?因为5.2。FDIS的6表示,“i ++”的结果是一个(p)右值,并且只讨论操作数('i')是一个可修改的左值。 – Xeo 2011-05-13 05:35:55

+0

我有2003年的版本。C99做同样的事情,但用更少的措辞。如果它改变了一段时间以前的变化。 – 2011-05-13 05:52:04

+0

好的,所以'我++++'应该在C++ 98/03中有效(但是UB),但是在C++ 0x/11中肯定是无效的。 – Xeo 2011-05-13 05:56:49

1

要回答这个问题的:“你想要做什么”的观点:没有一点调用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

3

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

请注意,简单地说sizeof(++++i)是好的,因为没有评估。即使被评估,在C++ 11中说++++i也可以。

相关问题