3

可能重复:
为什么 std::cout 输出在发送 NULL 后完全消失

似乎如果你尝试:

 std::cout << NULL << endl;
 std::cout << "hell" << endl;

它什么也不打印,C++ IO 停止对所有后续输出工作。

但它在 C stdio 中工作正常:

 printf("%s\n", NULL);
 printf("%s\n", "hell"); 

(空值)

地狱

C++ IO不能做同样的事情有什么好的理由吗?

(根据评论进行编辑)好吧,说清楚,NULL 确实有一个类型,比如 const char*

const char* getxxx();  // may return NULL, 
cout << getxxx();      // won't work if NULL returned
4

2 回答 2

14

嗯?我认为没有理由cout仅仅因为您执行了就失败

std::cout << 0 << std::endl;

它应该输出0\n. 它确实如此。故事结局。

(如果您感到困惑,请在 C++ 中了解这一点#define NULL (0)。)

如果您写道:

T* p = 0;
std::cout << p << std::endl;

然后它将显示地址0,(通常为十六进制并填充到指针大小,因为这是查看指针的首选方式)。

(顺便说一句,你会得到使用 NULL 的 C 定义的行为,即#define NULL ((void*)0).)

只要你写

char* p = 0;
std::cout << p << std::endl;

您遇到了困难。现在你打电话

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

标准(第 27.7.3.6.4 节)对此表示:

要求s不得为空指针。

当你传递一个空指针时,规则 17.6.4.9 适用,它指出:

以下每一项都适用于 C++ 标准库中定义的函数的所有参数,除非另有明确说明。* 如果函数的参数具有无效值(例如函数域之外的值或对其预期用途无效的指针),则行为未定义。

所以你在“未定义的行为”的土地上。无法保证failbit会设置好并且程序会继续。


请注意,printf行为实际上并不取决于NULL. 它"%s"是导致作为字符串处理的格式字符串(指向以 NUL 结尾的字符序列的指针)。

于 2013-01-25T17:15:04.577 回答
2

printf("%s", str)不需要处理NULL字符串,因此通过传递NULL 您是在自找麻烦。

与 IOStreams 语义等价的语句是:

std::cout << static_cast<char const*>(NULL);

这也不是处理NULL字符串所必需的。

于 2013-01-25T17:24:43.267 回答