2011-08-20 63 views
6

如果我不實際訪問解除引用的「對象」,被取消引用空指針仍然不確定?解除引用空指針會成爲未定義的行爲?

int* p = 0; 
int& r = *p; // undefined? 
int* q = &*p; // undefined? 

一個稍微更實際的例子:我可以解引用空指針來區分重載嗎?

void foo(Bar&); 
void foo(Baz&); 

foo(*(Bar*)0); // undefined? 

好的,參考例根據標準絕對未定義的行爲:

空引用不能在良好定義的程序存在的,因爲只有這樣,才能創建這樣的參考將它結合到通過取消引用一個空指針,這導致未定義的行爲獲得的「對象」。

不幸的是,強調部分是模糊的。難道是結合部分導致未定義的行爲,或者是解引用部分是否足夠?

+0

[這個問題包含你想要的信息。](http://stackoverflow.com/questions/2474018/when-does-invoking-a-member-function-on-a-null-instance-result-in- undefined-behav) – GManNickG

+0

這必須是一個確切的重複。我知道我們已經討論過這個問題。 –

回答

2

是的,它是未定義的行爲,因爲規範說,「左值指定一個對象或函數」(在3.10節),它說*「操作符」「結果[dereferencing]是一個左值指向對象或函數「(在5.3.1節)。

這意味着沒有描述當您取消引用空指針時會發生什麼。這只是未定義的行爲。

+0

(有關SO的其他問題已經討論過了,所以我想我不再詳述)。 –

5
int& r = *p; // undefined? 

我想在這裏你已經即使你不確定的行爲不實際上使用r(或*p) - 解除引用的對象。因爲在這一步之後(即解引用空指針),程序的行爲不能被語言保證,因爲程序可能立即崩潰,這是UB的一種可能性。您似乎認爲僅讀取r的值纔可以使用 in real目的調用UB。我不這麼認爲。

此外,語言規範明確指出「解除引用空指針的效果」會調用未定義的行爲。它確實是而不是「效果實際上使用從空指針中取消引用的對象」調用UB。解引用空指針(或換句話說未定義的行爲)的效果並不意味着您將必然立即出現問題,或者在解引用空指針後立即崩潰。號它只是意味着,該程序行爲不是解引用空指針之後定義。也就是說,該程序可能正常運行,符合市場預期,從開始到結束。或者它可能會立即崩潰,或者幾分鐘,幾小時或幾天後崩潰。任何事情都可以發生隨時解引用空指針。

+0

我無法在標準中找到「解除引用空指針的效果」。你究竟在哪裏找到它? – fredoverflow

+1

@FredOverflow:§1.9/ 4(C++ 03)說'某些其他操作在本標準中被描述爲未定義的(例如,取消引用空指針的效果)。 [注意:本國際標準對含有未定義行爲的程序行爲沒有要求。 ]' – Nawaz

+0

FDIS用'例如試圖修改const對象的效果替換了空指針示例,這可能表示關於解除引用空指針的規則已經改變。 – fredoverflow

4

我認爲第二篇作品What every C programmer should know about Undefined Behavior可能有助於說明這個問題。

以博客的例子:

void contains_null_check(int *P) { 
    int dead = *P; 
    if (P == 0) 
    return; 
    *P = 4; 
} 

可能是優化(RNCE:冗餘空檢查Elimintation):

void contains_null_check_after_RNCE(int *P) { 
    int dead = *P; 
    if (false) // P was dereferenced by this point, so it can't be null 
    return; 
    *P = 4; 
} 

這是週轉優化成(DCE:死代碼消除) :

void contains_null_check_after_RNCE_and_DCE(int *P) { 
    //int dead = *P; -- dead store 
    //if (false)  -- unreachable branch 
    // return; 
    *P = 4; 
} 

正如你所看到的,即使dead從不使用,簡單的int dead = *P賦值導致未定義的行爲在程序中蠕變。

爲了區分重載,我建議使用一個指針(可以爲null),而不是人爲地創建一個空引用並將自己暴露給Undefined Behavior。

相關問題