2014-09-22 75 views
8

一個朋友告訴我,後:是`C == C++`未定義的行爲?

int C = anything; 

C == C++將具有值true。這是作爲一個笑話,對經常聲稱的「C與C++不一樣」的反駁。

但是,由於==不是序列點,我認爲這實際上是未定義的行爲。該程序可能首先評估C++,以便C > C++C == C++都未定義。但是,C >= C++將始終評估爲true。當操作數翻轉時(C++ <= C始終爲真,其他所有內容都未定義)當然也是如此。

這種分析是否正確?

+5

所有的'C == C++','C> = C++'等都是未定義的。 – 2014-09-22 00:55:44

+0

[嘗試它](http://ideone.com/eknvOx)顯示,至少使用Ideone當前使用的特定編譯器版本和設置,結果恰好出現錯誤。 – user2357112 2014-09-22 00:56:46

+0

警告告訴它很清楚:http://coliru.stacked-crooked.com/a/1125dd5ddf7c41f9 – Csq 2014-09-22 00:56:48

回答

13

所有病例導致undefined behavior和不可預知的結果。

draft C++11 standard告訴我們,除非另有說明,否則操作數的評估順序是不確定的,如果相同的標量對象被非順序和副作用修改的次數多於我們未定義的行爲。如果我們需要修改對象並且必須爲另一個操作數計算對象的值,那麼它也是未定義的。這是覆蓋在草案C++ 11標準部1.9

除非另有說明,個體經營者 的和個別表達式子表達式的操作數的評價是未測序。注:在執行程序期間多次評估的表達式中,在不同的評估中不需要一致地執行對其子表達式的評估,其子表達式不需要一致地執行 。 - 結束符]運算符的運算結果的值計算 在運算符的結果之前被排序。如果標量對象上的副作用是 相對於同一標量對象的另一副作用或使用相同標量對象的值計算的值不相關,則行爲不確定。

無論是相等運算符或關係運算符在區段5.9關係運算符5.10相等運算指定操作數測序。

clang還提供了一個預警這種情況下,它看起來像在默認情況下,它應該類似於以下(see it live)的東西:

warning: unsequenced modification and access to 'C' [-Wunsequenced] 
    if(C == C++) 
     ~ ^

這也是C++ 03未定義行爲沒有使用排序關係的概念,但只是sequence points。在C++草案標準03的相關部分將Chapter 5表達式它說:

除非另有說明,個體經營者 和個人表達的子表達式的操作數的計算順序,以及訂單 在其中發生的副作用是未指定的.57)在 前一個和下一個序列點之間,通過評估表達式,一個標量對象最多應該修改其存儲的 值。 此外,只有在訪問先前值時才能確定要存儲的值。對於完整的 表達式的子表達式的每個允許排序,本段的要求應滿足 ;否則行爲是不確定的。

這是更簡單的理由,因爲多個修改或修改和使用相同序列點內的標量的值是未定義的行爲,無需弄清操作的順序。

1

你是對的。即使編譯器是這麼說的:編制

#include <iostream> 

int main() 
{ 
    int C = 0; 
    if (C == C++) { 
    ... 

結果:

main.cpp: In function 'int main()': 
main.cpp:6:17: warning: operation on 'C' may be undefined [-Wsequence-point] 
    if (C == C++) { 
       ^

Coliru

+0

對於一個編譯器(和一組設置)這可能是正確的。標準沒有要求編譯器診斷這一點。而一些編譯器則沒有。 – Peter 2015-07-17 09:01:05