Why Does Std::Cout Output Disappear Completely After Null Is Sent to It

Why does std::cout output disappear completely after NULL is sent to it

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?

Why can std::cout print the value of nullptr only if returned by a function?

Here is the meaning of nullptr from the CPP Standards [4.10]

  • A null pointer constant is an integral constant expression (5.19) prvalue of integer type that evaluates to zero or a prvalue of type std::nullptr_t. A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type and is distinguishable from every other value of object pointer or function pointer type. Such a conversion is called a null pointer conversion.

Something the CPP Standards specifies, is that it isn't a std::nullptr_t value, it evaluates to zero or a prvalue of type std::nullptr_t.

In your case, it's pretty much is an (TYPE) pointer to some extent, so when you try to paste it out, it pastes out it's type's value (Where it points to, but by itself it won't). Your function returns an int*, and you give it a nullptr. So what you are basically doing is giving an int* a value. nullptr by itself won't have a value but

int* abc = nullptr;

will.

Ignored parameters in std::cout after NULL

The operator has a precondition:

Requires: s shall not be a null pointer.

By breaking this precondition, you cause undefined behaviour. Anything could happen.

(As mentioned in the comments, one popular implementation sets failbit and badbit in this case, which would explain the behaviour you see. But that's not something you can rely on.)

What is the reason C++ std IO doesn't output NULL gracefully?

Huh? I see no reason why cout should fail simply because you executed

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

It should output 0\n. And it does. End of story.

(In case you're confused, please know that in C++, #define NULL (0).)

In case you wrote:

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

then it will display the address 0, (generally in hexadecimal and padded to the pointer size, since this is the preferred way of looking at pointers).

(This is btw the behavior you would get using the C definition of NULL, which is #define NULL ((void*)0).)

Only if you write

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

are you in trouble. Now you're calling

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

for which the Standard (section 27.7.3.6.4) says:

Requires: s shall not be a null pointer.

When you do pass a null pointer, the rule 17.6.4.9 applies, which states that:

Each of the following applies to all arguments to functions defined in the C++ standard library, unless explicitly stated otherwise.
* If an argument to a function has an invalid value (such as a value outside the domain of the function or a pointer invalid for its intended use), the behavior is undefined.

So you're in the land of "undefined behavior". There's no guarantee that failbit gets set and the program continues.


Please note that printf behavior didn't actually depend on the type of NULL. It's the format string "%s" that caused treatment as a string (pointer to NUL-terminated character sequence).

Does cout<<(char*)NULL doing close(1) here?

Here you sets the badbit on the stream which causes nothing to be printed after cout<<(char*)NULL;

if (!__s)
__out.setstate(ios_base::badbit);

The standard says: requires: shall not be a null pointer. So your program definitely has the undefined behavior and it should be fixed. You can clear the bad bit by using cout.clear().

In your case, cout<<(char*)NULL; causes undefined behavior. But GCC plays it safely.

Hope this helps!

why I can't cout after using string tokenizer

Sooner or later ptr=strtok(NULL," ") will return a null pointer. Which you immediately try to output leading to a null-pointer dereference and undefined behavior (and a very probable crash).

I suggest you modify your loop to something like this:

char *ptr = std::strtok(s, " ");
while (ptr != nullptr)
{
std::cout << ptr << '\n';
ptr = std::strtok(nullptr, " ");
}

Note the order in which things are done, and which guarantees that ptr will never be a null pointer when you output it.

std::cout while more text is output underneath

So upon further research, it can be done, but it's operating system specific.
The example I found is:

#include <iostream>
#include <windows.h> //This is where you will get the SetConsolePosition and
Coords struct

int main (void) {

COORD coord;
coord.X = 10;
coord.Y = 1;

std::cout << "Hello!" << std::endl;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
std::cout << "World!?" ;
return 0;
}

Is printing a null-pointer Undefined Behavior?

basic_ostream's operator<<(basic_ostream<>&, const char*) function requires that the char* is non-null - it is designed to print the string the pointer points to. So it is undefined behavior to send a null char* to cout. (See C++11 27.7.3.6.4/3 "Character inserter function templates").

However, basic_ostream's operator<<(basic_ostream<>&, const void*) function simply prints the value of the pointer, so a null pointer will work properly with that overload.

C++ - Null Pointers

char *ptr = 0;
cout << ptr;

There's an overload of the << operator that takes a char* operand, which it assumes is a pointer to a C-style string.

For pointer types other than char*, the << operator would print the value of the pointer (which is an address), but treating a null char* pointer as if it pointed to a C-style string causes undefined behavior. In any case, it's not going to print the pointer value.

To print the pointer value, you can convert it to void*:

cout << "test1\n";
char *ptr = 0;
cout << static_cast<void*>(ptr) << "\n";
cout << "test2" << "\n";;


Related Topics



Leave a reply



Submit