2010-09-03 31 views
17

OK,我有點不好意思問這個問題,但我只是想確保...短路評價和副作用

據瞭解,C使用短路評價布爾表達式:

int c = 0; 
if (c && func(c)) { /* whatever... */ } 

在這個例子func(c)不叫,因爲c計算結果爲0。但是更復雜的例子比較的副作用會改變接下來要比較的變量嗎?就像這樣:

int c; /* this is not even initialized... */ 
if (canInitWithSomeValue(&c) && c == SOMETHING) { /*...*/ } 

功能canInitWithSomeValue返回true和變化值在成功的情況下給出的指針。是否保證後續比較(本例中的c == SOMETHING)使用canInitWithSomeValue(&c)設置的值?

無論編譯器使用多麼繁重的優化?

+0

我想你可能會混淆短路評估和編譯器優化。在第一個例子中,編譯器會優化整個if語句,因爲它永遠不會運行。短路評估意味着如果你在運行時有if(func1()&& func2()){...}'和func1()評估爲false **(即編譯時沒有定義),那麼代碼不應該檢查'func2()' - 編譯器應該製作機器代碼,以便如果'func1()'爲false,則不調用'func2()'。 – Stephen 2010-09-03 12:35:51

+0

在比較的時候,'int c = 0'表明'c'等於'0',我意識到在簡單的情況下編譯器會優化整個'if'。 – 2010-09-03 12:53:32

+0

啊,我很抱歉。我誤解了你。我很抱歉。 – Stephen 2010-09-03 13:46:23

回答

23

是否保證後續比較(本例中爲c == SOMETHING)使用由canInitWithSomeValue(& c)設置的值?

是。因爲有一個sequence point

&&(邏輯與)左右操作數,||(邏輯OR)和逗號運算符的計算之間。例如,在表達式*p++ != 0 && *q++ != 0中,在任何嘗試訪問q之前,子表達式* p ++!= 0的所有副作用都已完成。


的序列點限定在它被保證先前評價的所有的副作用將已被執行在計算機程序的執行的任何點,並且還沒有被執行無副作用從後續評估。

+0

很好的答案,謝謝! – 2010-09-03 12:55:48

5

是的。因爲&&||運算符也是所謂的序列點。後者定義何時前一次手術的副作用應該完成,下一次手術的副作用是否應該開始。

1

if語句複合條件內的評估嚴格從左到右。在if中進行第二次測試的唯一情況是,如果編譯器可以100%確定地確定第一次測試的結果與假相同。