Significance of ios_base::sync_with_stdio(false); cin.tie(NULL); - c++

What is the significance of including
ios_base::sync_with_stdio(false);
cin.tie(NULL);
in C++ programs?
In my tests, it speeds up the execution time, but is there a test case I should be worried about by including this?
Do the 2 statements always have to be together, or is the first one sufficient, i.e., ignoring cin.tie(NULL)?
Also, is it permissible to use simultaneous C and C++ commands if its value has been set to false?
https://www.codechef.com/viewsolution/7316085
The above code worked fine, until I used scanf/printf in a C++ program with the value as true. In this case, it gave a segmentation fault. What could be the possible explanation for this?

The two calls have different meanings that have nothing to do with performance; the fact that it speeds up the execution time is (or might be) just a side effect. You should understand what each of them does and not blindly include them in every program because they look like an optimization.
ios_base::sync_with_stdio(false);
This disables the synchronization between the C and C++ standard streams. By default, all standard streams are synchronized, which in practice allows you to mix C- and C++-style I/O and get sensible and expected results. If you disable the synchronization, then C++ streams are allowed to have their own independent buffers, which makes mixing C- and C++-style I/O an adventure.
Also keep in mind that synchronized C++ streams are thread-safe (output from different threads may interleave, but you get no data races).
cin.tie(NULL);
This unties cin from cout. Tied streams ensure that one stream is flushed automatically before each I/O operation on the other stream.
By default cin is tied to cout to ensure a sensible user interaction. For example:
std::cout << "Enter name:";
std::cin >> name;
If cin and cout are tied, you can expect the output to be flushed (i.e., visible on the console) before the program prompts input from the user. If you untie the streams, the program might block waiting for the user to enter their name but the "Enter name" message is not yet visible (because cout is buffered by default, output is flushed/displayed on the console only on demand or when the buffer is full).
So if you untie cin from cout, you must make sure to flush cout manually every time you want to display something before expecting input on cin.
In conclusion, know what each of them does, understand the consequences, and then decide if you really want or need the possible side effect of speed improvement.

This is to synchronize IOs from C and C++ world. If you synchronize, then you have a guaranty that the orders of all IOs is exactly what you expect. In general, the problem is the buffering of IOs that causes the problem, synchronizing let both worlds to share the same buffers. For example cout << "Hello"; printf("World"); cout << "Ciao";; without synchronization you'll never know if you'll get HelloCiaoWorld or HelloWorldCiao or WorldHelloCiao...
tie lets you have the guaranty that IOs channels in C++ world are tied one to each other, which means for example that every output have been flushed before inputs occurs (think about cout << "What's your name ?"; cin >> name;).
You can always mix C or C++ IOs, but if you want some reasonable behavior you must synchronize both worlds. Beware that in general it is not recommended to mix them, if you program in C use C stdio, and if you program in C++ use streams. But you may want to mix existing C libraries into C++ code, and in such a case it is needed to synchronize both.

It's just common stuff for making cin input work faster.
For a quick explanation: the first line turns off buffer synchronization between the cin stream and C-style stdio tools (like scanf or gets) — so cin works faster, but you can't use it simultaneously with stdio tools.
The second line unties cin from cout — by default the cout buffer flushes each time when you read something from cin. And that may be slow when you repeatedly read something small then write something small many times. So the line turns off this synchronization (by literally tying cin to null instead of cout).

Using ios_base::sync_with_stdio(false); is sufficient to decouple the C and C++ streams. You can find a discussion of this in Standard C++ IOStreams and Locales, by Langer and Kreft. They note that how this works is implementation-defined.
The cin.tie(NULL) call seems to be requesting a decoupling between the activities on cin and cout. I can't explain why using this with the other optimization should cause a crash. As noted, the link you supplied is bad, so no speculation here.

There are lots of great answers. I just want to add a small note about decoupling the stream.
cin.tie(NULL);
I have faced an issue while decoupling the stream with the CodeChef platform. When I submitted my code, the platform response was "Wrong Answer" but after tying the stream and testing the submission. It worked.
So, If anyone wants to untie the stream, the output stream must be flushed.

Related

about a sync_with_stdio(0); and cin.tie(0); please help me [duplicate]

What is the significance of including
ios_base::sync_with_stdio(false);
cin.tie(NULL);
in C++ programs?
In my tests, it speeds up the execution time, but is there a test case I should be worried about by including this?
Do the 2 statements always have to be together, or is the first one sufficient, i.e., ignoring cin.tie(NULL)?
Also, is it permissible to use simultaneous C and C++ commands if its value has been set to false?
https://www.codechef.com/viewsolution/7316085
The above code worked fine, until I used scanf/printf in a C++ program with the value as true. In this case, it gave a segmentation fault. What could be the possible explanation for this?
The two calls have different meanings that have nothing to do with performance; the fact that it speeds up the execution time is (or might be) just a side effect. You should understand what each of them does and not blindly include them in every program because they look like an optimization.
ios_base::sync_with_stdio(false);
This disables the synchronization between the C and C++ standard streams. By default, all standard streams are synchronized, which in practice allows you to mix C- and C++-style I/O and get sensible and expected results. If you disable the synchronization, then C++ streams are allowed to have their own independent buffers, which makes mixing C- and C++-style I/O an adventure.
Also keep in mind that synchronized C++ streams are thread-safe (output from different threads may interleave, but you get no data races).
cin.tie(NULL);
This unties cin from cout. Tied streams ensure that one stream is flushed automatically before each I/O operation on the other stream.
By default cin is tied to cout to ensure a sensible user interaction. For example:
std::cout << "Enter name:";
std::cin >> name;
If cin and cout are tied, you can expect the output to be flushed (i.e., visible on the console) before the program prompts input from the user. If you untie the streams, the program might block waiting for the user to enter their name but the "Enter name" message is not yet visible (because cout is buffered by default, output is flushed/displayed on the console only on demand or when the buffer is full).
So if you untie cin from cout, you must make sure to flush cout manually every time you want to display something before expecting input on cin.
In conclusion, know what each of them does, understand the consequences, and then decide if you really want or need the possible side effect of speed improvement.
This is to synchronize IOs from C and C++ world. If you synchronize, then you have a guaranty that the orders of all IOs is exactly what you expect. In general, the problem is the buffering of IOs that causes the problem, synchronizing let both worlds to share the same buffers. For example cout << "Hello"; printf("World"); cout << "Ciao";; without synchronization you'll never know if you'll get HelloCiaoWorld or HelloWorldCiao or WorldHelloCiao...
tie lets you have the guaranty that IOs channels in C++ world are tied one to each other, which means for example that every output have been flushed before inputs occurs (think about cout << "What's your name ?"; cin >> name;).
You can always mix C or C++ IOs, but if you want some reasonable behavior you must synchronize both worlds. Beware that in general it is not recommended to mix them, if you program in C use C stdio, and if you program in C++ use streams. But you may want to mix existing C libraries into C++ code, and in such a case it is needed to synchronize both.
It's just common stuff for making cin input work faster.
For a quick explanation: the first line turns off buffer synchronization between the cin stream and C-style stdio tools (like scanf or gets) — so cin works faster, but you can't use it simultaneously with stdio tools.
The second line unties cin from cout — by default the cout buffer flushes each time when you read something from cin. And that may be slow when you repeatedly read something small then write something small many times. So the line turns off this synchronization (by literally tying cin to null instead of cout).
Using ios_base::sync_with_stdio(false); is sufficient to decouple the C and C++ streams. You can find a discussion of this in Standard C++ IOStreams and Locales, by Langer and Kreft. They note that how this works is implementation-defined.
The cin.tie(NULL) call seems to be requesting a decoupling between the activities on cin and cout. I can't explain why using this with the other optimization should cause a crash. As noted, the link you supplied is bad, so no speculation here.
There are lots of great answers. I just want to add a small note about decoupling the stream.
cin.tie(NULL);
I have faced an issue while decoupling the stream with the CodeChef platform. When I submitted my code, the platform response was "Wrong Answer" but after tying the stream and testing the submission. It worked.
So, If anyone wants to untie the stream, the output stream must be flushed.

Question about differences in standard I/O optimization for cin and cout

As a competitive programmer, I've always used ios::sync_with_stdio(0); to speed up cin and cout. But I've also seen other people use optimizations like cin.sync_with_stdio(0); or cout.sync_with_stdio(0);. For example, the latter two were used in this website: https://usaco.guide/general/fast-io?lang=cpp.
I know that ios::sync_with_stdio(0); unsyncs iostream(cin and cout) from stdio(scanf and printf), so why would someone unsync only the input cin or only the output cout when doing competitive programming (which usually has a large amount of both input and output)?
sync_with_stdio is a static method, cin.sync_with_stdio(0) does "exactly" the same as ios::sync_with_stdio(0);.
Not really exactly as it odr-uses std::cin but it is no-op.

why we need to close a file to complete the writing process of a file? [duplicate]

I understand cout << '\n' is preferred over cout << endl; but cout << '\n' doesn't flush the output stream. When should the output stream be flushed and when is it an issue?
What exactly is flushing?
Flushing forces an output stream to write any buffered characters. Read streamed input/output.
It depends on your application, in real-time or interactive applications you need to flush them immediately but in many cases you can wait until closing the file and leave the program to flush it automatically.
When must the output stream in C++ be flushed?
When you want to be sure that data written to it is visible to other programs or (in the case of file streams) to other streams reading the same file which aren't tied to this one; and when you want to be certain that the output is written even if the program terminates abnormally.
So you would want to do this when printing a message before a lengthy computation, or for printing a message to indicate that something's wrong (although you'd usually use cerr for that, which is automatically flushed after each output).
There's usually no need to flush cerr (which, by default, has its unitbuf flag set to flush after each output), or to flush cout before reading from cin (these streams are tied so that cout is flushed automatically before reading cin).
If the purpose of your program is to produce large amounts of output, either to cout or to a file, then don't flush after each line - that could slow it down significantly.
What exactly is flushing?
Output streams contain memory buffers, which are typically much faster to write to than the underlying output. Output operations put data into the buffer; flushing sends it to the final output.
First, you read wrong. Whether you use std::endl or '\n'
depends largely on context, but when in doubt, std::endl is
the normal default. Using '\n' is reserved to cases where
you know in advance that the flush isn't necessary, and that it
will be too costly.
Flushing is involved with buffering. When you write to
a stream, (typically) the data isn't written immediately to the
system; it is simply copied into a buffer, which will be written
when it is full, or when the file is closed. Or when it is
explicitly flushed. This is for performance reasons: a system
call is often a fairly expensive operation, and it's generally
not a good idea to do it for every characters. Historically,
C had something called line buffered mode, which flushed with
every '\n', and it turns out that this is a good compromize
for most things. For various technical reasons, C++ doesn't
have it; using std::endl is C++'s way of achieving the same
results.
My recommendation would be to just use std::endl until you
start having performance problems. If nothing else, it makes
debugging simpler. If you want to go further, it makes sense to
use '\n' when you're outputting a series of lines in just
a few statements. And there are special cases, like logging,
where you may want to explicitly control the flushing.
Flushing can be disastrous if you are writing a large file with frequent spaces.
For example
for(int i = 0 ;i < LARGENUMBER;i++)
{//Slow?
auto point = xyz[i];
cout<< point.x <<",",point.y<<endl;
}
vs
for(int i = 0 ;i < LARGENUMBER;i++)
{//faster
auto point = xyz[i];
cout<< point.x <<",",point.y<<"\n";
}
vs
for(int i = 0 ;i < LARGENUMBER;i++)
{//fastest?
auto point = xyz[i];
printf("%i,%i\n",point.x,point.y);
}
endl() was often know for doing other things, for example synchronize threads when in a so-called debug mode on MSVC, resulting in multithreaded programs that, contrary to expectation, printed uninterrupted phrases from different threads.
I/O libraries buffer data sent to stream for performance reasons. Whenever you need to be sure data has actually been sent to stream, you need to flush it (otherwise it may still be in buffer and not visible on screen or in file).
Some operations automatically flush streams, but you can also explicitly call something like ostream::flush.
You need to be sure data is flushed, whenever for example you have other program waiting for the input from first program.
It depends on what you are doing. For example, if you are using the console to warn the user about a long process... printing a series of dots in the same line... flushing can be interesting. For normal output, line per line, you should not care about flushing.
So, for char based output or non line based console output, flushing can be necessary. For line based output, it works as expected.
This other answer can clarify your question, based on why avoiding endl and flushing manually may be good for performance reasons:
mixing cout and printf for faster output
Regarding what is flushing: when you write to a buffered stream, like ostream, you don't have any guarantee that your data arrived the destination device (console, file, etc). This happens because the stream can use intermediary buffers to hold your data and to not stop your program. Usually, if your buffers are big enough, they will hold all data and won't stop your program due to slow I/O device. You may have already noticed that the console is very slow. The flush operation tells the stream that you want to be sure all intermediary data arrived on the destination device, or at least that their buffers are now empty. It is very important for log files, for example, where you want to be sure (not 100%) a line will be on disk not in an buffer somewhere. This becomes more important if your program can't loose data, i.e., if it crashes, you want to be sure you did you best to write your data on disk. For other applications, performance is more important and you can let the OS decide when to flush buffers for you or wait until you close the stream, for example.

Turbo C++ cin() not working along with gets()

Here is a code snippet I have written using c++ in turbo C++ IDE. The problem I am facing is after using gets(), cin is not working as it is skipping the inputs.Can someone possibly provide a solution to this issue.
Here is the code snippet :-
#include<iostream.h>
#include<conio.h>
#include<stdio.h>
int Resc()
{
char fName[10],lName[10],addr[100],usr[70],pass[20];
int d,y,m;
unsigned int phNo;
char *Gend;
clrscr();
cout<<"Enter First Name :"<<endl;
gets(fName);
cout<<"Enter Last Name :"<<endl;
gets(lName);
cout<<"Enter Gender :"<<endl;
gets(Gend);
cout<<"Enter Address:"<<endl;
gets(addr);
cout<<"Enter Date Of Birth (d/m/y):"<<endl;
cin>>d>>m>>y;
cout<<"Enter Phone Number :"<<endl;
cin>>phNo;
cout<<"Enter Username:"<<endl;
gets(usr);
cout<<"Enter Password:"<<endl;
gets(pass);
getch();
return 0;
}
It would be a great help. Thanks.
Turbo-C++ is ancient. There are free compilers available that are much better. Though I realize that in some countries, unfortunately it is still required by educators. However, if there is any way you can use an alternative, you should. The code you are learning to write right now won't compile on compilers actually used in the industry. This will cause problems for you in future jobs.
gets is the worst function ever to make it into a language standard library. It is impossible to use correctly. Don't ever use it. Excise its existence from your mind.
Don't mix C and C++ I/O. It leads to tricky issues where they get out of sync. Use one or the other, exclusively. If you use C I/O, use scanf and fgets with stdin, not gets. If you use C++ I/O, use cin exclusively. Note that parsing a "d/m/y" date with cin is a bit tricky. On the other hand, using cin would allow you to use string instead of character arrays, which would be infinitely superior. (For example, it would mean you can enter names longer than 9 characters without making your program do weird things.)
Gend should probably be a single char instead of a pointer pointing at nothing. This part of your program is just wrong and extremely likely to misbehave or crash.
Phone numbers are not integers. They often start with zeros, in typical usage contain punctuation and whitespace, and are long enough to overflow an unsigned int. (The moment you use an area or carrier prefix, the integer interpretation is likely more than 4000000000.) Use strings to store phone numbers, always.
Basically, gets() is not a C++ function (it is there because the whole C library is available to C++)
The thing is that you are messing usage of buffered input (using stdio package) with buffered C++ input system. And buffers hit to each other.
Don't mix stdio and c++ buffered I/O systems, as you'll get this kind of problems. What's happening inside of Turbo C++'s implementation is far from being able to check, as 1) you haven't disclosed which TC++ version you are using and 2) I have no such compiler at hand to make tests.

cin statement will not compile

Alright, I have a programming challenge due but unfortunately, although my code does in theory, doesn't work so I was wondering if it was a compiler issue (I use Code::Blocks) or if its something I'm not seeing. Any help would be appreciated, Thanks!
Here's my code:
#include <iostream>
#include <string>
#include <math.h>
using namespace std;
int main(){
double sliceStore, sliceSize = 14.125, totalSlice, area;
cout << "How Many Slices?" << endl;
//getline(cin,sliceStore);
cin >> sliceStore >> endl;
return 0;
}
Remove "endl" from the input statement !!
The complete error message for this is not nice and goes on for a few pages, but code::blocks usually fronts GCC and g++, GCC's C++ compiler, should have started the message of with something like this:
cin >> sliceStore >> endl;
^
In English, the compiler could not find a way for the >> operator to put data into endl. A bit of reading up on what endl is may have solved your problem. endl is a function, not a variable.
ostream& endl(ostream&)
Crack your textbook and read up on input and output streams.
cin is the name of an input stream attached to the main console, usually represented by the command prompt. Input streams use >>, which is also a function, one that usually looks like
istream& operator>>(istream&, somedatatype&)
So cin >> endl; really looks like is a function call something like
cin = operator>>(cin, endl());
However, no one has built an operator>> with a somedatatype that looks like ostream& endl(ostream&) and the compiler prints out a huge list of operator>> possibilities that look something like it as a hint of what you might have meant to do.
Most of the time this is helpful. Most functions only have a couple overloads, and you can quickly see what you did wrong. But operator>> has an overload for every common datatype and dozens of not so common data types. Blah.
Onto what the endl function does.
It tells an output stream to do two things: to end the line and to flush the output buffer.
Ending the line's pretty simple, the only caveat is everybody seems to do it differently so if you compile the same program under different operating systems you'll get slightly different output.
The output buffer flush is a instruction to the output stream to send any data it's been holding onto, buffering, for a good chance to send it.You generally want to send stuff in chunks because it's more efficient. Say you want to write to a file. In the world of a computer where things happen in nanoseconds, writing to a file can take seconds. For example, the hard disk could be in a low power sleep state and have to start spinning. Then it has to find where the file goes on the hard drive. Then it has to wait for the hard drive to spin into the right position. You don't want to go through all that just to write one character as each time you press a key on the keyboard, so the computer builds up a bunch of writes in memory--the buffer--thee writes the contents of the buffer after it fills up, hasn't been added to for a while, or is forced to with a flush instruction. endl provides that flush. As a result, overuse of endl can slow down your program.