为什么std :: cout输出在发送NULL后完全消失 [英] Why does std::cout output disappear completely after NULL is sent to it

查看:804
本文介绍了为什么std :: cout输出在发送NULL后完全消失的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我花了一段时间才弄清楚为什么一些cout输出似乎消失在以太。罪魁祸首:

  std :: cout< 这行显示很好<< std :: endl; 
const char * some_string = a_function_that_returns_null();
if(some_string == 0)
std :: cout<< 让我们检查some_string的值:< some_string<< std :: endl;

std :: cout<< 此行和任何cout输出之后将不会显示< std :: endl;

上述代码段的输出将是:

 这行显示正好
让我们检查some_string的值:

因此,将一个NULL送入cout将禁用所有输出。为什么?和如何解决它?



这并不总是发生 - 具有相同代码的同事获得所有预期的输出。如果你想知道为什么我不能仅仅阻止喂一个if语句cout:我在一个大的代码库工作,不知道在哪里发生这种情况!我所知道的是我从来没有出现的cout语句。






更多信息:



a_function_that_returns_null()实际上是 getenv(HOST)。我在命令行上通过 echo $ HOST 检查HOST变量是否为空。如果我做 export HOST = (bash flavor),输出都存在。我不知道HOST变量最初包含什么和什么 getenv 最初返回时,我修改HOST变量之前;所有我知道是(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不为null。


然后流 some_string 是未定义行为;你不能取消引用一个指针来获取一个字符串—甚至一个空的如果指针无效。







这不会一直发生 - 具有相同代码的同事获得所有预期的输出


UB导致不可靠的症状。因为大多数现代操作系统在尝试取消引用时会总是 SIGSEGV ,所以您并不总是遇到崩溃,这可能会令人惊讶。空指针。



但是,从C ++的角度来看,任何事情都可能发生。在你的特殊情况下,你的标准库实现可能正在检查一个空指针,并在流上设置一个错误标志,而不是尝试取消引用指针。这是它的特权。



(这也可能是为什么你的后续流操作失败:当设置了错误标志时,尝试写入流不会做任何事) p>

例如,使用GCC 4.6.0附带的libstdc ++,尽管命名 s!= 0 作为前提条件 执行此操作

  00325 if(!__ s)
00326 __out.setstate(ios_base :: badbit);
00327 else

但是,依赖此行为;它可以随时更改








std :: string 有什么问题?


It took me a while to figure out why some cout output seem to disappear into the ether. The culprit:

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;

The output from the snippet above will be:

This line shows up just fine
Let's check the value of some_string:     

So feeding a NULL into cout will disable all output afterward. Why? And how to fix it?

This doesn't happen all the time - a co-worker with the same code gets all the expected output. And in case you wonder why I can't just prevent feeding NULL into cout with a if statement: I'm working in a large codebase, and don't know where else this happens! All I know is the cout statements I put never showed up.


More info:

a_function_that_returns_null() is actually getenv("HOST"). I checked on the commandline via echo $HOST that the HOST variable is empty. If I do export HOST= (bash flavor), the output are all there. I have no idea what the HOST variable contains initially nor what getenv returns initially when before I modify the HOST variable; all I know is (some_string == 0) is true.

解决方案

const char* some_string = a_function_that_returns_null();

Do you mean that it literally returns a null pointer?

[2003: 27.6.2.5.4]:

template<class traits>
basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>& out, const char* s);

3. Requires: s is non-null.

Then streaming some_string is Undefined Behaviour; you cannot dereference a pointer to get a string — even an empty one — if the pointer is not valid.


This doesn't happen all the time - a co-worker with the same code gets all the expected output

UB leads to unreliable symptoms. That you don't always get a crash can be slightly surprising because most modern OSs make a point of always SIGSEGVing when you try to dereference a null pointer.

However, from a C++ point of view, anything can happen; in your particular case, your standard library implementation may well be checking for a null pointer and setting an error flag on the stream instead of attempting to dereference the pointer. That is its prerogative.

(It's also probably why your subsequent stream operations are failing: attempting to write to a stream does nothing when there's an error flag set.)

For example, the libstdc++ that ships with GCC 4.6.0, despite naming s != 0 as a precondition, does do this:

00325       if (!__s)
00326     __out.setstate(ios_base::badbit);
00327       else

However, you must not rely on this behaviour; it could change at any time!


So, simply don't do this. Stream a valid, but empty, string if you really must.

And what's wrong with std::string?

这篇关于为什么std :: cout输出在发送NULL后完全消失的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆