Case(s) where output buffer won't flush? - c++

I am learning about iostream objects and flushing the buffer. I know when output buffers are guaranteed to be flushed and how to explicitly flush the buffer. However, I have never seen a case where output buffer is not flushed. It seems to me that output buffer gets flushed at the end of each statement even if I don't use manipulators such as endl, flush and ends.
So, is there any simple example(s) where the output buffer will not ( or at least, might often not) get flushed? I feel like I need to see such a case to really understand output buffers.

Depends on the system.
Take the following program as an example:
#include <iostream>
#ifdef WIN32
#include <windows.h>
#define sleep(n) Sleep((n)*1000)
#else
#include <unistd.h>
#endif
using namespace std;
int main()
{
cout << "This is line 1";
sleep(4);
cout << endl;
cout << "This is line 2" << endl;
return 0;
}
By inspecting the program, you might surmise that the program would print This is line 1, followed by pausing for 4 seconds, then printing This is line 2.
And if you compile with Visual Studio to run on Windows, you'll get that exact behavior.
On Linux and other Unix operating systems however, the program will appear to be silent for 4 seconds before printing out both lines together. The output won't reliably flush until a new line character is encountered in the output stream.

Related

Why printf is executed before cout after using ios::sync_with_stdio(false) in c++?

#include <iostream>
#include <stdio.h>
int main () {
std::ios::sync_with_stdio(false);
std::cout << "hi from c++\n";
printf("hi from c\n");
return 0;
}
After removing std::endl and putting \n instead in cout statement the output changed to the following:
hi from c
hi from c++
It's a buffering issue.
By default when standard output is connected to a terminal, stdout is line-buffered meaning the buffer is flushed and output actually written to the terminal on newline.
When C stdio is disconnected from the C++ standard streams, std::cout is fully buffered, meaning output is actually written when either explicitly flushed (using e.g. std::flush or std::endl manipulators) or if the buffer is full.
The two buffers used by C stdout and C++ std::cout are different and not connected.
Flushing of the buffers also happens when the program exits.
What happens in your program is that the output with printf is flushed immediately because of the trailing newline in the string. But the output to std::cout is only flushed when the program exits.

Why does the output comes after sleep without newline?

I'm using gcc 7.3 and g++ 7.3. GCC and G++ makes error. For example,
#include <stdio.h>
#include <unistd.h>
int main() {
printf("a");
sleep(1);
return 0;
}
'a' prints after waiting 1 seconds but when I use printf("a\n"); it works correctly. It's same on C++. For example,
#include <iostream>
#include <unistd.h>
int main() {
std::cout << "a";
sleep(1);
return 0;
}
'a' prints after waiting 1 seconds, too. However, when I use std::cout << "a" << std::endl; it works correctly. What's the problem and how to fix it?
sleep() is like schedule a process manually. printf() puts the data into stdout stream not directly on monitor.
printf("a"); /* data is there in stdout , not flushed */
sleep(1); /* as soon as sleep(1) statement occurs your process(a.out) jumped to waiting state, so data not gets printed on screen */
So either you should use fflush(stdout) or use \n to clear the stdout stream.
You are seeing this behaviour because stdout will be usually line buffered when used with terminal and fully buffered when used with files, the strings will be stored in a buffer and can be flushed by entering new line or when buffer fills or when program terminates
You can also override buffer mode by using setvbuf as below
setvbuf(stdout, NULL, _IONBUF, 1024);
printf("a");
It will print a without buffering, have a look at https://www.tutorialspoint.com/c_standard_library/c_function_setvbuf.htm for using setvbuf
Also have a look at different types of buffering with streams.
Hope this helps you.

Why reading from a stream does not require a buffer flush

Just started C++ learning by C++ Primer 5th ed.
The very first example of the book on page 6 is as followed
#include <iostream>
int main()
{
std::cout << "Enter two numbers:" << std::endl;
int v1 = 0, v2 = 0;
std::cin >> v1 >> v2;
std::cout << "The sum of " << v1 << " and " << v2
<< " is " << v1 + v2 << std::endl;
return 0;
}
The manipulator endl insert newline and flush the buffer.
soon followed by the code snipe in the page 7, the author emphasized that
Programmers often add print statements during debugging. Such
statements should always flush the stream. Otherwise, if the program
crashes, output may be left in the buffer, leading to incorrect
inference about where the program crashed
From the code example and the emphasized warning I feel it is important to do the flush when writing to a Stream
Here is the part I don't understand, how a bout reading from a stream case, such as std::cin, is there any necessary to do the flush then?
Appended Question:
#include <iostream>
int main()
{
int sum = 0, val = 1;
while (val <= 5) {
sum += val;
++val;
std::cout << sum << std::endl; //test
}
}
When I changed the line marked with test to std::cout << sum << '\n';, there is no visual difference in the console. Why is that, isn't it supposed to print as follows if there is no flush for each loop?
1
1 3
1 3 6
1 3 6 10
1 3 6 10 15
Thanks
Even if #Klitos Kyriacou is right when he says you should create a new post for a new question, it seems to me that both your questions arise from the same misunderstanding.
Programmers often add print statements during debugging. Such statements should always flush the stream. Otherwise, if the program crashes, output may be left in the buffer, leading to incorrect inference about where the program crashed
This quote does not mean that you need to flush every buffer in your program to create any output on the console.
By flushing the buffers you can make sure that the output is printed before the next line of code is executed.
If you don't flush the buffers and your program finishes, the buffers will be flushed anyway.
So, the reason you see the same output on the console with std::endl and \n is, that exactly the same text is printed to the console. In the former case, the output might be there slightly earlier, as the buffers are flushed early. In the latter case, the buffers are flushed later, but they will be flushed at some time.
What the quote talks about is the case when your program does not exit gracefully, e.g. when your program crashes or is interrupted by the OS. In these cases, your output might not be written to the console when you did not explicitly flush the buffers.
What the quote wants you to know is: Whenever you want to debug a program that crashes, you should explicitly flush the buffers to make sure your debug output is printed to the console before your program is interrupted.
Note that this might not be true for all implementations.
From http://en.cppreference.com/w/cpp/io/manip/endl
In many implementations, standard output is line-buffered, and writing '\n' causes a flush anyway, unless std::ios::sync_with_stdio(false) was executed.
Quote from the same book page 26:
Buffer A region of storage used to hold data. IO facilities often store input (or out-put) in a buffer and read or write the buffer
independently from actions in the program. Output buffers can be
explicitly flushed to force the buffer to be written. Be default,
reading cin flushes cout; cout is also flushed when the program ends
normally.

Difference between endl & '\n' and their relation with flushing the output buffer?

I've just stepped into the world of competitive programming and therefore, was reading few articles to grasp the best strategies a programmer should follow while writing code in c++.
I read somewhere that one should use '\n' in lieu of std::endl at the end of the line because std::endl forces the buffer to flush.
I didn't know what 'flushing of buffer' meant so I started searching for it and came across this answer What does flushing the buffer mean? After reading the answer the idea that I got 'flushing the buffer' was to print & wipe out everything in the output buffer to the console.
So, to check the validity of the answer I made this program on my machine.
#include <iostream>
#include <time.h>
using namespace std;
int main()
{
struct timespec tim, tim2;
tim.tv_sec = 3;
tim.tv_nsec = 0;
for(int i=0; i<5; i++)
{
cout << i << endl;
nanosleep(&tim , &tim2);
}
return 0;
}
The results I got on executing the program came as expected. The loop printed 0 to 4 with a delay of 3 seconds after each iteration.
However, when I changed endl to '\n' I was expecting the results to show on the console all at once after 15 seconds. But, the digits got outputted after the same delay it got outputted in the previous case. Now, if '\n' doesn't flush the output buffer, shouldn't I've got the results as I was expecting?
std::endl forces a flush of the stream. This does not mean that no flush will happen without it.
In general, the standard library will flush std::cout (and, yes, other streams are treated differently) even if the output buffers are not full if std::cout points to a tty and the buffers ends with \n. In your second case, that is precisely what's happening.
If you want to see your code working as you expect it, try redirecting the output to a file (and then watch the file with tail -f). That will cause the standard output not to be a tty, and thus not cause a flush on \n.
Also, IIRC, std::cerr is flushed on \n whether it is a TTY or not. If you write to a file, it should never flush unless you explicitly flush (e.g., with std::endl).
Edited to add
I couldn't get it to work with either stderr or stdout, but the following does print all numbers at the end:
#include <iostream>
#include <fstream>
#include <time.h>
using namespace std;
int main()
{
struct timespec tim, tim2;
tim.tv_sec = 3;
tim.tv_nsec = 0;
ofstream out("output");
for(int i=0; i<5; i++)
{
out << i << "\n";
nanosleep(&tim , &tim2);
}
return 0;
}
You dont have full control over when the buffer is flushed. Some systems flush it when you insert a \n into the stream, others dont.
Just because flush does flush the stream it does not mean that not calling flush will cause the stream to not flush.

Why does g++ make my code execute in a different order than written and how do I disable this "optimization"?

For example:
#include <stdio.h>
#include <string>
int main() {
std::string* stuff(NULL);
printf("allocating memory..."); //line 2
stuff = new std::string[500000000]; //line 3
delete [] stuff; //line 4
return 0;
}
when executed runs line 3 (and possibly line 4) before line 2. Now I know this is probably some good optimization feature but sometimes the right order is needed.
The problem is here:
printf("allocating memory..."); //line 2
In many architectures you have buffered output, which means that what you print on the screen is not shown immediately but stored in a memory buffer. To flush the buffer and ensure that he is printed immediately, you can use
printf("allocating memory...\n"); //line 2 with the \n character that flushes the buffer
although I didn't find anything to prove this besides personal experience, or alternatively, if you don't want to go to a new line (and be absolutely sure of flushing) you can use fflush(stdout) right after line 2.
In C++, you might want to write it like this:
#include <iostream>
#include <string>
int main() {
std::string* stuff(NULL);
std::cout << "allocating memory..."; //line 2
std::cout.flush(); // ensures the buffer is actually written to the terminal right here
stuff = new std::string[500000000]; //line 3
delete [] stuff; //line 4
return 0;
}
-O0 flag disables all optimizations in GCC.
But the effect you are observing is most probably not due to an optimization but rather a result of file IO buffering.
Inserting fflush(stdout) just after printf(...) will make IO system flush the buffer which in case of logging to a file should give you the right order of events (assuming you are logging malloc() calls to the same file and this is where you observe out of order events).