繁体   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