2009-09-10 55 views
1

我目前正在使用Diab 4.4 C++編譯器。這是一個總的POS,不符合ANSI標準,過去我發現它存在問題。retval = false && someFunction(); //是否調用someFunction()?

我想知道如果下面的問題是編譯器的問題,或者在我的C++

知識的缺點我意識到,X = X & & y的形式;如果x是假的,將使y部分短路。編譯器正在做的事情是在x = x & & y()的情況下短路。其中y()是一個非const函數。

class A 
{ 
int _a; 
A(int a) { _a = a; } 
bool someFunction() { _a = 0; return true; } 
}; 

main(...) 
{ 
A obj = A(1); 
bool retval = false; 

retval = retval && A.someFunction(); 

/* What is the value of A._a here? */ 
} 

什麼似乎是錯誤的我是編譯器做其實這短路即使someFunction()是不是一個const函數。如果它不是const,那麼當retval爲false時,編譯器是否通過跳過A.someFunction()來超越它的界限?

此外,我認識到這個問題可以通過寫入retval = A.someFunction()& & retval;但我真的很想知道爲什麼會發生這種情況。

回答

7

&&||運營商被定義爲懶惰評估,這是語言的工作方式。如果您希望始終發生副作用,請首先調用該函數並存儲結果,或者重構該函數以從狀態查詢中分離工作。

+0

沒有意識到評價是懶惰的。現在更有意義。 – 2009-09-10 17:48:17

+0

...或使用&如果兩個操作數都是/返回布爾值。 – RJFalconer 2009-12-31 15:55:22

10

短路適用於所有表達式,無論const -ness。跳過someFunction()的電話是正確的。

4

如果&&的第二個操作數是常量或不是那麼重要。在第一個操作數計算結果爲false之後,返回值是已知的,因此沒有理由評估第二個操作數。

如果函數具有需要執行的副作用,請先放置它。

2

短路評估與const或非const無關。無論發生什麼,都會發生。

陳述A() && B();將完全做if (A()) B();(儘管它不是一個完美的替代品,因爲第二個允許else)。這有時用於將語句更改爲表達式(例如在寫入宏或將其嵌入到另一個語句中時)。

+0

請注意,只有** && **表單是一個右值。你不能說:** C = if(A())B(); ** – NVRAM 2009-09-10 18:24:04

+0

是的,它更接近C = A()?除A()之外的A():B()被評估一次。 – MSalters 2009-09-11 10:11:35

+0

請記住,C在C中返回0或1,在C++中返回false或true。它不會返回任何一個操作數,除非它們的值爲0或1,或者爲false或true。 – 2009-09-11 13:58:10

1

該& &運算符也被稱爲快捷操作符,這意味着它只評估第二部分,如果第一部分返回true。這是& &和&之間的主要區別在於:

value = func1() && func2(); // evaluates func2() only if func1() returns true 

value = func1() & func2(); // evaluates both func1() and func2() 
+1

實際上,'&&'和'&'與僅有短路行爲有很大不同。 '((0x10 && 0x01)== 1)'但是((0x10&0x01)== 0)'。 – 2009-09-10 18:18:24

+0

當然,我正在討論評估布爾值。 – 2009-09-10 18:20:16

1

對於& &操作,

1 && X = X 
0 && X = 0 

這樣的情況下,第一var爲0,編譯器會計算表達式爲0,毫無疑問,什麼都X是。

編譯器會忽略X部分,因爲它不會影響結果。這裏X可以是任何函數/變量/表達式.....

+0

這並不能說明整個故事。當然編譯器會這樣做,如果表達式的左邊部分可以靜態地知道是真的還是假的。但是,此外,即使左手錶達式複雜,也會在AT RUNTIME時發生。這是C++語言定義的一部分。 – 2009-09-10 22:58:05

+0

這也是不準確的。 1 && X不會返回X,除非X碰巧是一個布爾值。在C++中,&&返回true或false;在C中它返回0或1。 – 2009-09-11 13:59:17

5

正如其他人所說的那樣,和& &總是執行短路評估。

還要注意的是短路計算可以非常有用,因爲它可以讓你寫這樣的代碼:

retval = obj_pointer && obj_pointer->SomeBooleanMethod(); 

沒有短路評價,這將崩潰的一個NULL指針。

相關問題