2012-06-25 64 views
8

我知道,寫東西像序列點來自哪裏?

++a = a++; 

不僅是不可讀的,而且違反了C/C++序列點。

這些限制來自哪裏?在發現錯誤之前,如何看待這些「問題」?

+0

那麼,它仍然是一種語言設計限制,還是一種機器(cpu)限制,對任何語言都是通用的? –

+5

錯誤:對'a'的操作可能是未定義的[-Werror = sequence-point]' - 啊,謝謝你,方便的編譯器。 – chris

+1

打開你的所有警告,並將它們作爲邏輯錯誤進行編譯和處理,你不需要擔心這個:'-Werror -Wall -Wextra -ansi -pedantic' –

回答

8

基本上每個語句之間都有一個C++ 03序列點。欲瞭解更多信息,請參閱SO C++ FAQ。有關更多信息,請參閱C++標準,並記住在C++ 11標準中,序列點被替換爲之前的之間的順序關係爲

爲了避免出現問題,根本不要試圖在每個表達式中做太多巧妙的事情。

不要試圖編譯器的工作:把它留給編譯器。你的工作是編寫其他人可以很容易理解的代碼,即明碼。帶有副作用的操作員多次更新和不必要的使用與此不兼容。

提示:幾乎所有可能的情況下撒上const

這限制了讀者必須考慮的可能的狀態變化。

+0

謝謝你的答案。我希望我能在這裏'接受'許多答案;) –

4

How can one see those 'problems' before finding them as bugs?

以最嚴格的級別編譯您的程序,並將所有警告的設置指出爲錯誤。大多數主流編譯器都指出由於序列點導致的未定義行爲錯誤。

與海灣合作委員會,你可以使用:

-Wsequence-point 

其中應指出的序列點的問題。請注意,如果您使用-Wall,則默認啓用。

當然,最好的方法是嘗試編寫更多可讀代碼,避免序列點錯誤冒險

+2

@chris:'-Wall'默認啓用它,正如我已經提到的那樣。 –

+0

的確,我誤解了它。 – chris

+0

用於'-Wsequence-point'選項的+1。我不知道。 – Nawaz

7

它們來自C或C++標準,它有效地列出了sequence points。 在一些簡單的情況下,您的編譯器可能會警告您調用了未定義的行爲,但在一般情況下不會。

但是,如果您正在撰寫「有趣」的代碼(如您的示例),則通常只會違反序列點要求。語言標準可能對諸如此類的代碼(這是Java這樣的語言)施加了特定的限制,但是沒有多大的優勢,以及防止某些類型的優化的潛在缺點。


1. C++ 11中的術語略有變化,但我認爲原理在很大程度上保持不變。

+0

謝謝你的答案。我希望我能在這裏'接受'許多答案;) –

+0

我前一段時間回答了一個關於C++ 98和C++ 11之間差異的問題:http://stackoverflow.com/a/10655884/365496 – bames53