1

我知道C中的計算順序並不嚴格,因此表達式--a + ++a的值未定義,因爲不知道聲明的哪部分首先運行。在同一語句中使用幾個遞增/遞減

但是,如果我知道計算順序在特定情況下無關緊要怎麼辦?例如:

  1. 所有修改對應於不同的變量(如在a[p1++] = b[p2++]
  2. 訂單並不重要,像a++ + ++a - 結果是兩個無論哪個的+側首先計算。是否可以保證在運行另一個零件之前完全計算一個零件?即編譯器無法記憶a++的結果,++a的結果,然後申請第一個a++,得到一個而不是兩個?例如,緩存初始值a並將其作爲參數獨立傳遞給兩個運算符。

我對C,C99,C11,C++ 03和C++ 11的答案感興趣,如果它們之間有任何區別的話。

回答

3

標準表示:

之前和下一序列點的對象應具有由 表達的評估改性至多一次 其存儲的值之間。此外,先前的值只能訪問到 確定要存儲的值。/26/

除由語法/ 27所指示/或另有說明以後 (對於函數調用運營商(),& &,||:和逗號 運營商),評價的順序的子表達式和 中發生的副作用的順序都沒有說明。

所以:

1)a[p1++] = b[p2++]:這是保證語句正確評估,給出了預期的結果。這是因爲每個變量只修改一次,結果不取決於兩個變量的實際增量完成時間。

2)a++ + ++a:不保證在第二次使用a之前執行副作用(增量)。因此,該表達式可以給出值a + (a+1)(a+1) + (a+1)a + (a+2),具體取決於編譯器何時執行原始變量的副作用增量。

0

Online C 2011 standard

6.5表達式
...
3符和操作數的分組是由語法表示。 85)除指定 後, 副作用和子表達式的值計算是不確定的86)

85)的語法SPECI音響上課符的優先級中的表達的評價,這是相同的 如本節,最高優先級第一個主要的子節的順序。因此,例如,所述 表達式允許作爲二進制運算符+(6.5.6)的操作數是這些表達式代音響通過6.5.6定義在 6.5.1。 (6.5.4)作爲一元運算符 (6.5.3)的操作數,以及包含在以下任何一對運算符之間的操作數:分組 括號()(6.5.1),下標括號[](6.5 .2.1),函數調用括號()(6.5.2.2),和 條件運算? :(6.5.15)。 在每個主要子條款中,運營商具有相同的優先級。左或右關聯性是在每個子條款中通過其中討論的表達式的語法來指示的。 86)在程序執行期間多次評估的表達式中,未定序的和不定序的子表達式評估不需要在 不同的評估中一致地執行。

着重號。

有沒有保證,其他表達式求值前副作用或者a++++a應用,所以你可以根據操作的順序得到不同的結果。

下面是一些例子,假設在a 1開始時:

  • 左到右的評價,副作用立即應用:(1)+(2 + 1)== 4
  • 左到右評估,推遲的副作用:(1)+(1 + 1)== 3
  • 右到左評估,立即應用副作用:(2)+(1 + 1)== 4
  • 右到左評估,副作用延遲:(1)+(1 + 1)== 3

或任何其他組合。