void main(void)
{
int x,y,z;
x=y=z=1;
z = x && y && ++z;//is this fine?
}
我最近開始閱讀關於序列點的東西,但我無法弄清楚上面的代碼示例是否正確。我知道&&
算子引入了一個序列點,所以我不太確定表達式z = x & & y & & ++ z的行爲。有人請告訴我正確的答案。複雜的表達式涉及邏輯AND(&&)
void main(void)
{
int x,y,z;
x=y=z=1;
z = x && y && ++z;//is this fine?
}
我最近開始閱讀關於序列點的東西,但我無法弄清楚上面的代碼示例是否正確。我知道&&
算子引入了一個序列點,所以我不太確定表達式z = x & & y & & ++ z的行爲。有人請告訴我正確的答案。複雜的表達式涉及邏輯AND(&&)
是的,它會編譯。
但如果你問的邏輯錯誤:
1)&&
運營商引入序列點,因爲它可以終止,當它確切地知道最終結果的表達式求值(在這種情況下0
值可以終止評估),所以如果x
或y
爲零,它甚至不會達到++z
部分。 2)因爲&&
運算符是邏輯運算符,結果總是爲0或1,我懷疑這是你想要的。
在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給了寶貴的投入從原來的版本
@Prasoon Saurav:你在哪? – Chubsdad 2010-10-03 14:12:17
@Chubsdad:根據'x'和'y'的值,行爲將是未定義的。但是我們有'x = 1'和'y = 1',所以'++ z'的評估是有保證的,因此這個行爲是不確定的,因爲'z'在兩個序列點之間被修改了不止一次[賦值和預增量修改'z'兩次,沒有任何中間順序點]。請注意,您的文章包含C++ 0x草稿的引用。在C++中0x'i = ++ i'是一個明確定義的行爲。 – 2010-10-03 14:16:10
立即向上投票。 :) – 2010-10-03 14:25:20
一個簡單的方法提煉這個帖子知道,如果這條線是罰款還是不就是讓編譯器檢查。例如,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
令人沮喪的是,gcc需要一個特殊的選項來產生這個警告,而不是僅僅爲這樣的代碼生成'movb $ 0,0'或者等價物。 – 2010-10-03 16:07:50
在C和用C'主()'應'int' ++的返回類型。 – 2010-10-03 14:28:29