[英]Why does std::cout output disappear completely after NULL is sent to it
我花了一段時間才弄清楚為什么一些 cout output 似乎消失在了以太中。 罪魁禍首:
std::cout<< "This line shows up just fine" << std::endl;
const char* some_string = a_function_that_returns_null();
if (some_string == 0)
std::cout<< "Let's check the value of some_string: " << some_string << std::endl;
std::cout<< "This line and any cout output afterwards will not show up" << std::endl;
上面代碼段中的 output 將是:
This line shows up just fine
Let's check the value of some_string:
因此,將 NULL 輸入 cout 之后將禁用所有 output。 為什么? 以及如何解決?
這不會一直發生 - 具有相同代碼的同事會獲得所有預期的 output。 如果你想知道為什么我不能用 if 語句阻止將 NULL 輸入 cout:我正在一個大型代碼庫中工作,不知道還會發生這種情況。 我所知道的是我提出的 cout 聲明從未出現過。
更多信息:
a_function_that_returns_null()
實際上是getenv("HOST")
。 我通過echo $HOST
在命令行上檢查了 HOST 變量是否為空。 如果我確實export HOST=
(bash 風格),那么 output 都在那里。 在我修改 HOST 變量之前,我不知道 HOST 變量最初包含什么,也不知道getenv
最初返回什么; 我所知道的是(some_string == 0)
是真的。
const char* some_string = a_function_that_returns_null();
你的意思是它真的返回一個 null 指針嗎?
[2003: 27.6.2.5.4]:
template<class traits> basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>& out, const char* s);
3.要求:s 非空。
然后流式傳輸some_string
是未定義的行為; 如果指針無效,則不能取消引用指針來獲取字符串——即使是空字符串。
這不會一直發生 - 具有相同代碼的同事獲得所有預期的 output
UB導致不可靠的症狀。 您並不總是會崩潰可能有點令人驚訝,因為當您嘗試取消引用 null 指針時,大多數現代操作系統都會強調始終SIGSEGV
ing。
但是,從 C++ 的角度來看,任何事情都可能發生; 在您的特定情況下,您的標准庫實現很可能正在檢查 null 指針並在 stream 上設置錯誤標志,而不是嘗試取消引用指針。 這是它的特權。
(這也可能是您隨后的 stream 操作失敗的原因:嘗試寫入 stream 在設置錯誤標志時什么都不做。)
例如,GCC 4.6.0 附帶的 libstdc++,盡管將s != 0
作為前提條件,但確實這樣做:
00325 if (!__s)
00326 __out.setstate(ios_base::badbit);
00327 else
但是,您不能依賴這種行為; 它可能隨時改變!
所以,干脆不要這樣做。 Stream 一個有效但為空的字符串,如果你真的必須的話。
std::string
有什么問題?
我相當確定cout << (char*)NULL
具有未定義的行為。 恐怕“不要那樣做”是我能提供的最好建議。
當您嘗試 output const char*
時, stream 會打印所有字節,直到達到'\0'
。 它導致未定義的行為。 例如,您可以打印一些控制符號(即'\n'
、 '\r'
等)並得到不可預知的結果。
編輯:實際上 NULL 指針的流式傳輸足以獲得 UB。 由於有用的評論,我不會刪除我的答案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.