2011-05-13 67 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也可以。

相關問題