簡體   English   中英

為什么std :: cout output在NULL發送給它后完全消失

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM