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 SIGSEGV
ing 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
How Could Pairing New[] With Delete Possibly Lead to Memory Leak Only
Comparing a Variable to a Range of Values
C++ Dynamic Shared Library on Linux
What Are Some Uses of Decltype(Auto)
Detecting Superfluous #Includes in C/C++
How Is "=Default" Different from "{}" for Default Constructor and Destructor
How to Get Memory Usage At Runtime Using C++
Does Const Mean Thread-Safe in C++11
How to Make My Program Watch For File Modification in C++
Displaying the #Include Hierarchy For a C++ File in Visual Studio
Combining Several Static Libraries into One Using Cmake
Why Can't We Declare a Std::Vector≪Abstractclass≫
What's the Scope of Inline Friend Functions
What Requirements Must Std::Map Key Classes Meet to Be Valid Keys