2011-07-16 35 views
12
int& fun() 
{ 
    int * temp = NULL; 
    return *temp; 
} 

在上面的方法中,我試圖做一個NULL指針的解除引用。當我調用這個函數時,它不會例外。我發現什麼時候返回類型是通過引用它不會給出例外,如果它的價值,那麼它的確如此。即使將NULL指針的解引用分配給引用(如下面的行),它也不會給出。通過解引用NULL指針來分配引用

int* temp = NULL: 
int& temp1 = *temp; 

這裏我的問題是,不編譯器在引用的情況下做解引用?

+4

引用在內部作爲指針處理,它們在您使用的語法上只是不同。知道你的取消引用只是「分配」指向該引用的指針值,使其成爲NULL的引用。這不會觸發任何內存訪問。當你按值返回時,取消引用將導致0的內存訪問,這幾乎總是給你一個段錯誤。 – Nobody

+0

檢查這篇文章,這解釋了爲什麼空指針是OOP中的一個可怕的功能,應該盡一切可能避免:http://www.yegor256.com/2014/05/13/why-null-is-bad.html – yegor256

回答

16

取消對NULL指針未定義行爲

一個未定義的行爲意味着什麼事情都有可能發生,所以這是不可能的定義此行爲。

誠然,我要添加這個C++標準的報價爲第n次,但似乎它需要。

關於未定義行爲,

C++標準部1.3.24狀態:

允許不確定的行爲的範圍從具有不可預知的結果完全無視的情況下,在一個或翻譯程序執行期間表現有記錄的環境特徵(有或者沒有發佈診斷消息),終止翻譯或執行(通過發佈診斷消息)。

注:
而且,只是將其帶到您的通知:
使用返回的引用或指針函數內部的局部變量也是一個未定義的行爲。你應該使用new在freestore(堆)上分配指針,然後返回一個引用/指針給它。

編輯:
作爲@詹姆斯McNellis,適當地在評論指出,
如果不使用返回的指針或引用,該行爲良好限定

+0

是的,就上述UB達成一致。但我的問題是,如果取消引用NULL指針或非NULL指針是爲了將其分配給引用,那麼編譯器會執行取消引用操作嗎?像 - Int * t = NULL; Int&t1 = * t; –

+1

@G Mann:引用只是它初始化的初始類型的別名。它是如何實現的是編譯器的實現細節,標準沒有定義如何實現。 –

+2

當你使用空指針時,代碼無效,編譯器可以做任何事情。詢問爲什麼它做了什麼是沒有意義的。 –

7

當您取消引用空指針時,您不一定會得到異常;所有可以保證的是,行爲是不確定的(這實際上意味着根本不能保證行爲是什麼)。

一旦*temp表達式,就不可能推理的程序的行爲。

+0

我添加了與其他文章中所做的相同的評論 - 是的,同意上述UB。但我的問題是,如果取消引用NULL指針或非NULL指針是爲了將其分配給引用,那麼編譯器會執行取消引用操作嗎?像 - Int * t = NULL; Int&t1 = * t; –

+0

對於大多數編譯器來說,在很多情況下,引用是作爲指針來實現的。除此之外,它取決於編譯器,設置等。 –

+0

糾正我,我錯了。如果它作爲指針實現,那麼編譯器可能不會執行取消引用操作。 –

0

我不知道我知道你想什麼待辦事項。 ** NULL **指針的取消引用未定義。

如果你想表明您沒有方法總是返回值,你可以將它聲明爲:

布爾樂趣(INT & VAL);

或STL方式(類似於到std ::地圖插入):

std::pair<int, bool> fun(); 

或升壓方式:

boost::optional<int> fun(); 
4

您是允許取消引用空指針,所以假設你不這樣做,編譯器可以生成代碼。如果你這樣做,編譯器可能會很好,並告訴你,但它不必。這是你的合同的一部分,說你不能這樣做。

在這種情況下,我敢打賭編譯器很好,並告訴你在編譯時已經存在的問題,如果你只是正確設置警告級別。