2010-04-28 90 views
31

我想了解一下什麼的C++標準說,關於這樣的代碼:C++標準:取消引用NULL指針以獲取引用?

int* ptr = NULL; 
int& ref = *ptr; 
int* ptr2 = &ref; 

在實踐中,結果是ptr2爲NULL,但我不知道,這只是一個實現細節,或者這是明確定義在標準?
在不同的情況下,一個NULL指針的解引用應該導致崩潰,但是在這裏,我將它解引用以獲得由編譯器實現的引用作爲指針,所以實際上並沒有實際的NULL解引用。

+5

http://stackoverflow.com/questions/2474018/when-does-invoking-a-member-function-on-a-null-instance-result-in-undefined-behav正在提供一個非常好的答案問題。 – pmr 2010-04-28 08:32:00

+0

鏈接副本:[將一個NULL指針取消引用到未使用的引用;這也是「未定義行爲」?](http:// stackoverflow。com/q/40216965/514235) – iammilind 2016-10-24 11:22:03

回答

44

解引用NULL指針是未定義的行爲。

事實上的標準調用這個確切情況的一份說明(8.3.2/4「參考」):

注:尤其是空引用不能在一個明確的程序存在,因爲創建這種引用的唯一方法是將其綁定到通過取消引用空指針獲得的「對象」,這會導致未定義的行爲。


順便說一句:在有一次我在一個明確定義的方式所知道的,一個空指針可以「引用」是作爲操作的sizeof操作,因爲操作數sizeof實際上沒有被評估(所以解除引用從未實際發生)。

+5

事實上,如果它是'typeid'的操作數,並且它是一個'PolymorphClass *'類型的空指針,那麼它將被解除引用*和*求值。它仍然是定義良好的(拋出'bad_typeid')。我真的不喜歡那種特殊的'typeid'治療。 – 2010-04-28 16:42:15

+2

不允許NULL引用是不幸的。它展示了一些很酷的屬性,但我想這只是使代碼複雜化。 :(如果前提條件可用並且代碼可以更好地驗證,則可以安全地使用NULL引用。 – Adrian 2013-05-24 22:58:47

+1

sizeof()是一個變量類型的運算符,而不是值NULL指針的類型是 – jforberg 2015-06-09 17:40:34

1

解引用NULL指針是未定義的行爲。在解引用它之前,你應該檢查一個值是否爲NULL。

2

取消引用NULL指針在C++標準中是顯式未定義的行爲,所以您看到的是實現特定的。在C++ 0X標準草案從1.9.4

複製(在這方面類似於先前標準):

某些其他操作被描述 本國際標準如 未定義(例如, 解引用空指針的效果)。 [注意:此國際標準 對 未定義行爲的程序的行爲沒有要求。 - 注完]

+1

這很有趣,因爲沒有人能夠顯示標準解引用的地方空指針是明確的製造UB。標準在這裏不正確。 – curiousguy 2011-11-29 02:53:28

+0

@curiousguy:8.3.2.5再一次暗指解引用空指針是未定義的事實。但你是對的,它的確如此,就好像它在別處解釋過一樣。無論如何,1.3.13解釋了任何沒有明確定義的行爲都被認爲是未定義的,所以情況可能如此。 – Gorpik 2011-11-29 10:39:30

+1

「8.3.2.5」順便說一句,它拼寫爲8.3.2/5。沒有8.3.2.5節。 「_任何未明確定義的行爲都被認爲是undefined_」你是對的:只有當指針指向一個對象時,纔會定義一個指針。但是,如果標準明確地表明瞭這一點 - 將會稍微清晰一些 - 而且電子墨水將花費在這個非問題上。 – curiousguy 2011-11-29 11:19:24

1

爲了完整起見,這個:http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#232會談具體這個問題。

+0

嗯...非常有創意的想法。因此,調用一個null'this'的成員函數是允許的!我不知道他們在吸菸。無論如何,7年後,這個瘋狂的方向沒有做任何事情。 – curiousguy 2011-11-29 03:03:17

+0

其實它不是,根據http://stackoverflow.com/a/2474021/399317(由於左值到右值的轉換) – Kos 2012-08-23 17:49:22

+0

有趣的是,#232使用除零作爲UB的一個例子,當許多C++實現隱含地包含了IEEE-754,IEEE-754定義了除正負零的效果。 *整數*除以零是UB,但該示例沒有指定。 – supercat 2016-10-25 01:47:16

-2
int& ref = *ptr; 

上述聲明實際上並沒有對任何東西進行解引用。所以在使用ref(這是無效的)之前沒有問題。

+4

廢話。一元'*'實際上是**解引用運算符。它**實際上**執行取消引用操作。 – curiousguy 2011-11-29 02:54:50

+0

@curiousguy:我建議你編譯並在反彙編器中看到代碼。參考'ref'本質上是一個指針,所以上面的語句只是幕後的指針賦值。 – valdo 2011-11-29 15:20:01

+2

你誤解了我。我不在乎生成了什麼彙編代碼。根據你的情況,'* ptr'是什麼? – curiousguy 2011-11-29 16:23:49