2010-10-03 76 views
9
void main(void) 
{ 
    int x,y,z; 
    x=y=z=1; 

    z = x && y && ++z;//is this fine? 
} 

我最近開始閱讀關於序列點的東西,但我無法弄清楚上面的代碼示例是否正確。我知道&&算子引入了一個序列點,所以我不太確定表達式z = x & & y & & ++ z的行爲。有人請告訴我正確的答案。複雜的表達式涉及邏輯AND(&&)

+4

在C和用C'主()'應'int' ++的返回類型。 – 2010-10-03 14:28:29

回答

-2

是的,它會編譯。

但如果你問的邏輯錯誤:

1)&&運營商引入序列點,因爲它可以終止,當它確切地知道最終結果的表達式求值(在這種情況下0值可以終止評估),所以如果xy爲零,它甚至不會達到++z部分。 2)因爲&&運算符是邏輯運算符,結果總是爲0或1,我懷疑這是你想要的。

6

在C++ 03

void main(void) 
{ 
    int x,y,z; 
    x=y=z=1;         // Seq1 at ; 

    z = x && y && ++z;//is this fine?   // Seq2 at ; 
} 

注意:請注意,有序列點,運營商& &但後來這些都不是在這個例子中有關。

好!一般來說,可能是或可能不是。取決於x和y的值。在你的具體情況下,它不好。此代碼有可能具有所謂的undefined behavior

如果這些z- ++進行評估(如在你的例子,因爲x和y爲1),則標量變量「Z」被修改一次以上兩個序列之間的表達點SEQ1和SEQ2(見下文)。值得注意的是,賦值運算符不會引入任何序列點。

$ 5/4-「除非另有說明,順序 個體經營者和個人 表達式 子表達式,並且其中 副作用發生的順序的操作數的評價 ,是 unspecified.53 )先前 和下一個順序點的標 物體之間應具有由表達式的 評價改性至多一次它存儲的值 。 此外,前一個值是 僅訪問脫termine值 要存儲。該 段落的要求應符合每個 允許排序的 子表達式的完整表達式; 否則該行爲是不確定的。」

在C++ 0x中

會更新一次我自己理解的@litb簡稱討論的細節。就目前而言,我只是把它打掉了

但是在C++ 0X中,據我所知,沒有序列點的概念。這個表達式很好,不會調用未定義的行爲。這是因爲++對'z'的影響在'z'賦值的副作用之前被排序。

$ 1.9/15-「除非另有說明,單獨的 運營商的操作數和 單個表達式的子表達式的 評價是 未測序。[注:在表達 ,其期間評估多於一次 更一個程序的執行, 未測序和不定 測序其 子表達式的評估不需要在不同的評價進行 一致。的末端音符]的值計算210運算符的操作數是在運算符結果的值計算 之前排序的 。 如果標量對象上的 副作用是 未測序相對於同一標量對象 在任另一個 副作用或使用值相同的標量對象的 的值計算, 行爲是未定義的。

$ 7.8/9 - 「運算類型(3.9.1), 枚舉類型,指針類型, 指針成員類型(3.9.2), 的std :: nullptr_t,和CV-合格 版本的這些類型(3.9.3)是統稱爲標量類型的 。「

請注意,在表達式'z = z ++;'中其中z是一個標量變量,由賦值運算符和後綴運算符++引起的對'z'的副作用是不確定的(它們都沒有在另一個之前排序)。

感謝@Prasoon給了寶貴的投入從原來的版本

+2

@Prasoon Saurav:你在哪? – Chubsdad 2010-10-03 14:12:17

+2

@Chubsdad:根據'x'和'y'的值,行爲將是未定義的。但是我們有'x = 1'和'y = 1',所以'++ z'的評估是有保證的,因此這個行爲是不確定的,因爲'z'在兩個序列點之間被修改了不止一次[賦值和預增量修改'z'兩次,沒有任何中間順序點]。請注意,您的文章包含C++ 0x草稿的引用。在C++中0x'i = ++ i'是一個明確定義的行爲。 – 2010-10-03 14:16:10

+0

立即向上投票。 :) – 2010-10-03 14:25:20

2

一個簡單的方法提煉這個帖子知道,如果這條線是罰款還是不就是讓編譯器檢查。例如,gcc的the -Wsequence-point option(由-Wall啓用)用於檢查是否存在未定義的行爲,因爲缺少序列點。

你的程序

int main(void) 
{ 
    int x,y,z; 
    x=y=z=1; 

    z = x && y && ++z;/*is this fine?*/ 

    return 0; 
} 

產生這樣的警告:

 
x.c: In function 'main': 
x.c:6:5: warning: operation on 'z' may be undefined 
+0

令人沮喪的是,gcc需要一個特殊的選項來產生這個警告,而不是僅僅爲這樣的代碼生成'movb $ 0,0'或者等價物。 – 2010-10-03 16:07:50