Reputation: 558
In an effort to better understand buffered streams in C++, I would like to write a simple program in which the std::cout
buffer is NOT flushed before termination. Since I have read that std::cout
is flushed on normal termination, I tried throwing a runtime error. I also avoided using std::endl
, as I understand that forces a flush. First attempt:
//file noflush.cpp
#include <iostream>
int main() {
std::cout << "Don't write me to the console!";
throw 0;
}
Compile with g++, call from terminal:
$ ./noflush
libc++abi.dylib: terminating with uncaught exception of type int
Don't write me to the console!Abort trap: 6
Even when I force a runtime error, it seems the buffer still gets flushed on termination. Is it possible to "strand" some data in the buffer, leaving it unwritten to the device?
Upvotes: 13
Views: 2077
Reputation: 7
#include <iostream>
#include <sstream>
#include <vector>
int main()
{
std::stringstream cpature;
auto restore = std::cout.rdbuf(cpature.rdbuf());
std::cout.rdbuf(restore);
for(unsigned long int i = 0; i < 10000; ++i)
std::cout <<"Hello ! " << std::endl;
std::cout << "END" << std::endl;
std::cout << cpature.rdbuf();
std::vector<double> *p;
p->push_back(1.0);
delete p;
std::cout << "STILL ALIVE !" << std::endl;
}
Upvotes: 0
Reputation: 238311
This is not standard c++, but in POSIX, you can send a "kill" signal to kill the running process. This will stop the execution without cleanup such as flushing buffers.
Edit: I realized that signals are not only POSIX but actually part of C standard library (and included in the C++ standard library).
#include <csignal>
// ...
std::cout << "Don't write me to the console!";
std::raise(SIGKILL);
Upvotes: 10
Reputation: 45414
As far as I can tell, there is no standard compliant and clean way to avoid std::cout
to flush()
before program termination (but, of course, you can use unclean methods, e.g. raising a signal either directly or indirectly). According to cppreference, the actual buffer type controlled by std::cout
is implementation defined but derived from std::streambuf
, which does not appear to allow public access in a way that would emulate silent swallowing of the buffer.
Further, as I noted in a comment, even abnormal program termination (via std::terminate()
or std::abort()
may or may not close open resources, so this is again implementation defined.
Upvotes: 9
Reputation:
If I get you right, you want to capture or ignore the output to std::cout
:
#include <iostream>
#include <sstream>
int main()
{
// Capture the output to `std::cout`
{
std::cout << "[Capture Output]" << std::endl;
std::stringstream cpature;
auto restore = std::cout.rdbuf(cpature.rdbuf());
std::cout << "... captured output ..." << std::endl;
std::cout.rdbuf(restore);
std::cout << "[Enable Output]" << std::endl;
// Display the cpatured output.
std::cout << cpature.rdbuf();
}
std::cout << std::endl;
// Even more drasticly: Ignore the output to `std::cout`
{
std::cout << "[Ignore Output]" << std::endl;
auto restore = std::cout.rdbuf(nullptr);
std::cout << "... ignored output ..." << std::endl;
std::cout.rdbuf(restore);
std::cout << "[Enable Output]" << std::endl;
}
std::cout << "[End]\n";
}
Upvotes: 0
Reputation: 5191
With the following example, I can create the behaviour you want with gcc 4.8.3 :
#include <iostream>
#include <vector>
int main()
{
std::string str;
for(unsigned long int i = 0; i < 10000; ++i)
str += "Hello ! ";
str += "END";
std::cout << str;
std::vector<double>* p;
p->push_back(1.0);
delete p;
std::cout << "STILL ALIVE !" << std::endl;
return 0;
}
Then, the output is :
Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! Hello ! [...] Hello ! Segmentation fault
We can see than END
is not printed before the segmentation fault.
Upvotes: 4