2015-02-24 255 views
2

Xcode 6.3(測試版)給了我新的警告,任何建議如何解決這個問題?我不認爲把這個檢查完全刪除是一個正確的答案,因爲在某些情況下,「相機」已經爲NULL,並在其他地方導致崩潰。如何解決「引用不能綁定到解除引用空指針」警告

在定義明確的C++代碼中引用不能綁定到解除引用的空指針;可以假定比較始終評估爲假

以下是代碼。我還能如何驗證相機存在?

Camera& camera = sceneEngine->camera(); 
// FIXME: this triggers an undefined-bool-conversion warning in Xcode 6.3 BETA 
if (&camera == NULL) return; 

而且從SceneEngine相關的方法:

// HEADER 
class SceneEngine 
{ 
public: 
    Camera& camera(); 
protected: 
    Camera camera_; 
} 

// CPP 
Camera& SceneEngine::camera() { 
    return camera_; 
} 
+4

如果你有一個'相機&',然後將相機存在或您有未定義的行爲。沒有但是。 – immibis 2015-02-24 06:22:31

+0

所以你建議擺脫警告,我應該刪除檢查和處理崩潰(相機爲NULL時)以某種其他方式? – JOM 2015-02-24 06:26:49

+1

引用永遠不應該是NULL,它們總是指向一個實際的對象,除非你像在R Sahu的回答中所證明的那樣在地址0處強制一個對象存在的地方調用未定義的行爲。這個斷言不應該在那裏,或者你應該使用指針來代替。 – Havenard 2015-02-24 06:28:24

回答

6

由於camera對象由參考返回,它不能是空的,因爲引用總是指向一個實際存在的對象。

所以,如果你把一個引用變量的地址,它不能爲空,因爲它無論如何都指向一個有效的對象。

只需使用返回值而不進行任何空檢查。

PS。如果該函數返回對一個不存在對象的引用(例如null),那只是未定義的行爲。

解決方案:

如果camera()需要能夠在某些時候它的返回類型返回null,然後換Camera*能夠返回一個空指針。

否則 - camera()永遠不會返回空值,即它總是返回對有效對象的引用 - ,您不需要空的檢查,這就是錯誤信息所說的。

+0

你是對的:要麼我必須改變接口或確保相機永遠存在。我會選擇將Camera類型的返回類型更改爲Camera *,因爲其餘代碼似乎都期望這樣。創建一個丟失的相機將是一個更冒險的任務。感謝幾個解決方案的想法! – JOM 2015-02-24 07:24:20

1

看你行

if (&camera == NULL) return; 

我們可以問:這句話什麼時候會是真的嗎?答案只有當camera被綁定到一個取消引用的空指針時。

如果你有不好的代碼就像一個明顯的例子:

Camera* cameraPtr = NULL; 
Camera& camera = *cameraPtr; 

條件上述if語句將評估對true。如果camera可能綁定到這樣一個取消引用的指針,則if語句有一定的價值。否則,它沒有任何價值,編譯器會警告你。

你問:

怎麼我還能確認相機的存在呢?

當一個函數返回一個引用時,你必須假定函數返回一個有效的Camera對象並繼續使用它。刪除if行。

+1

'camera&camera = * cameraPtr;'當'cameraPtr'爲NULL時是未定義的行爲。 – immibis 2015-02-24 06:23:06

+0

@immibis,我明白在明確定義的代碼中就是這種情況。我提出了一個明顯的錯誤代碼案例。 – 2015-02-24 06:25:08

+0

好的,明白'Camera&camera = * cameraPtr;'可以讓你的程序崩潰。 – immibis 2015-02-24 06:33:36

4

由於語言標準定義您在引用NULL時已具有未定義的行爲,因此編譯器可以完全優化您的條件。因此,此代碼無用。警告會通知您這一點。

要使警告消失,您需要編寫代碼,以確保首先不會生成NULL引用。一,E,你這樣寫代碼之前:

void bar(Camera& cam); 
void foo(Camera* cam) { 
    bar(*cam); 
} 

你需要檢查的指針,你將它轉換成一個參考前:

void bar(Camera& cam); 
void foo(Camera* cam) { 
    if(cam) bar(*cam); //this works as desired 
}