为什么在发送NULL之后,std :: cout输出会完全消失
我花了一段时间才弄清楚为什么有些产量似乎消失在以太网中。 罪魁祸首:
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;
上面代码片段的输出将是:
This line shows up just fine Let's check the value of some_string:
所以给cout提供一个NULL将会禁用所有的输出。 为什么? 以及如何解决它?
这不会一直发生 – 具有相同代码的同事可以获得所有预期的输出。 而且如果你想知道为什么我不能防止用if语句把NULL喂给cout:我在一个大的代码库中工作,不知道这发生在哪里! 我所知道的是我所说的结论从未出现过。
更多信息:
a_function_that_returns_null()
实际上是getenv("HOST")
。 我通过echo $HOST
检查了命令行,HOSTvariables是空的。 如果我export HOST=
(bash flavor),输出全部在那里。 我不知道最初的HOSTvariables包含什么,也没有什么getenv
在我修改HOSTvariables之前返回的; 我所知道的是(some_string == 0)
是真的。
const char* some_string = a_function_that_returns_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是非空的。
然后streamsome_string
是未定义的行为; 如果指针无效,则无法取消引用指针来获取string – 即使是空string也是如此。
这不会一直发生 – 具有相同代码的同事可以获得所有预期的输出
UB导致不可靠的症状 。 你并不总是会崩溃,这可能会让你感到有些意外,因为当你试图解引用一个空指针的时候,大多数现代操作系统都总是使用SIGSEGV
。
然而,从C ++的angular度来看, 任何事情都可能发生 。 在你的特殊情况下,你的标准库实现可能正在检查一个空指针并在stream上设置一个错误标志,而不是试图解引用指针。 这是它的特权。
(这也可能是为什么你的后续stream操作失败:当设置了错误标志时,试图写入一个stream什么也不做。
例如,尽pipe命名s != 0
作为先决条件 ,但是与GCC 4.6.0一起提供的libstdc ++ 却 这样做 :
00325 if (!__s) 00326 __out.setstate(ios_base::badbit); 00327 else
但是, 你不能依赖这种行为 。 它可以在任何时候改变!
所以,根本不要这样做。 如果你真的需要,请input一个有效但空的string。
而std::string
什么问题?
我很确定cout << (char*)NULL
有未定义的行为。 恐怕“不要那样做”是我能提供的最好的build议。
当你试图输出const char*
,stream打印所有的字节,直到到达'\0'
。 这是导致未定义的行为。 例如,你可以打印一些控制符号(即'\n'
, '\r'
等),并得到不可预知的结果。
编辑 :其实stream空指针就足以得到UB。 由于有用的评论,我不会删除我的答案。