ivme
ivme

Reputation: 558

How to make a simple C++ program in which std::cout is not flushed

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

Answers (5)

Dirk Lindner
Dirk Lindner

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

eerorika
eerorika

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

Walter
Walter

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

user2249683
user2249683

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

Caduchon
Caduchon

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

Related Questions