2014-04-25 87 views
5

在研究this question的示例代碼時,我認爲這是未定義的行爲,它妨礙了打印後續使用std::cout。但事實證明,這是其無法運作的真正原因。因此,我現在好奇是否爲未定義的行爲(試圖)打印空指針。所以這裏是我的問題:正在打印空指針未定義的行爲?

  1. 它是未定義行爲打印空指針?如果是這樣,那麼會造成這種情況的流式插入器是什麼?我非常確定插入器足夠聰明,不能解引用空指針。

  2. 我也想知道爲什麼插件在遇到空指針的時候設置錯誤掩碼(特別是badbit)。爲什麼它不把它當作字符串文字的終止?

我沒有一個標準的方便,我只發現一個來源到目前爲止,不幸導致一個死鏈接。

+1

libstdC++在不需要時可能會執行額外的'nullptr'檢查。當你使用clang + libC++構建程序時,[seg faults](http://coliru.stacked-crooked.com/a/2078b21d2ce9050d)。但不是與鏗鏘+ libstdC++ – Praetorian

+2

「我敢肯定,插件是足夠聰明,不能解除引用空指針。」 - 一般來說,C++標準說明了編譯器必須做什麼以及其他任何事情,他們不需要做。它會減慢正確編碼的程序在每次調用operator <<(char *)'之前執行額外的NULL檢查。 –

+0

@MattMcNabb:lol我不認爲在處理像C++ I/O流那樣慢的事情時,空檢查的速度是一個問題。 – Mehrdad

回答

11

basic_ostreamoperator<<(basic_ostream<>&, const char*)函數要求char*非空 - 它被設計爲打印指針指向的字符串。因此,發送空char*cout是未定義的行爲。 (請參見C++ 11 27.7.3.6.4/3「字符插入器函數模板」)。

但是,basic_ostreamoperator<<(basic_ostream<>&, const void*)函數只是打印指針的值,所以空指針可以正常使用該超載。

+5

如果您通過'[ostream.inserters.character]'引用標準而不是'27.7。 3.6.4'那麼它有更多的機會在一個不同的版本中仍然是有效的參考,可能會重新編寫章節或章節。 –

2

GCC ostream.tcc行319:

template<typename _CharT, typename _Traits> 
    basic_ostream<_CharT, _Traits>& 
    operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s) 
    { 
    if (!__s) 
__out.setstate(ios_base::badbit); 

GCC簡單地進行檢查,該標準並不能保證,這是很好的,因爲它是不確定的反正。