Significance of Ios_Base::Sync_With_Stdio(False); Cin.Tie(Null);

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

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.

Why does moving around ios_base::sync_with_stdio(false), cin.tie(NULL) result in a memory error?

From [ios.members.static]/2:

Effects: If any input or output operation has occurred using the standard streams prior to the call, the effect is implementation-defined. Otherwise, called with a false argument, it allows the standard streams to operate independently of the standard C streams.

Furthermore, the cppreference page notes that

If this function is called after I/O has occurred on the standard stream, the behavior is implementation-defined: implementations range from no effect to destroying the read buffer.

I'm not entirely sure what exactly happened in your case. Reading the source of libstdc++ (e.g., here), which I assume is the standard library being used, it seems that it clears the buffers. This means that it's possible that some input you were waiting for was buffered, and your program either started reading from a strange spot or the reads just failed entirely. But the precise details and why that would have caused an out of memory error is beyond me.

(It's also worth noting that the fact you're calling it in a loop doesn't seem to be the problem in this implementation, as libstdc++ only clears the buffers if you're already unsynchronised with stdio.)

How do I interpret this behavior of ios_base::sync_with_stdio(false); cin.tie(NULL);?

The thing you're not really understanding is what it means to synchronize with things, as well as what standard input and standard output really are.

Standard Input and Standard Output are global resources for your process. Each process has one Standard Input and one Standard Output. cin represents a single way of reading from Standard Input. But scanf is another way of reading from it.

Standard Input is global. So if one method of reading data reads something, then another one comes along and tries to read stuff, well the stuff the second one tried to read may not be there anymore. Here's an example of how that might happen.

The statement cin >> test; will read something from standard input. How much something? Well, it will read at least enough to get a single long type. But cin is perfectly capable of reading much more than that. Typically, cin will read data based on an internal buffer size.

Currently, your initial input is just 2 <return>. However, it doesn't have to be. It could have been 2 2 2 2 2 10 <return>. cin >> test; will still only read a single integer. The rest will be unread input, which will be processed by the next cin read command.

However, will that unread input actually still be in the global Standard Input? Probably not; cin will likely read all of that data and shove it into an internal buffer. Once that happens, Standard Input contains nothing. Oh yes, using cin will process the rest of the 2 2 2 2 10 input.

But using scanf will not. Why? Because it doesn't know about cin's internal buffer. It only reads from Standard Input. And the same goes for scanf. It can have its own internal buffer of unread input, and cin can't read that.

Well, not unless you synchronize the two systems. That is exactly what sync_with_stdio is for: when it is set to true (as it defaults to), operations on the standard streams will work between the two systems. cin can read some characters, and scanf can read some others, and neither will miss anything.

If however you do not synchronize them, then you shouldn't try to use both systems in the same application. To do so runs the risk of input going missing, or output not appearing in the right order.


The behavior of cin.tie is exactly what the answer you linked to says: it ensures that stuff written to Standard Output will be displayed to the user before any attempts to read from Standard Input take place.

However, this only applies to cin and cout. scanf does not necessarily participate in such tying behavior (whether synchronization is active or not). As such, it is undefined if the cout statements will display anything to Standard Output before the scanf statements start reading from Standard Input.

So cin.tie does not apply to you.

std::ios_base::sync_with_stdio(false), advantages, disadvantages?

sync_with_stdio is a static function.

so

std::cout.sync_with_stdio(false);

is in fact

std::cout, std::ios_base::sync_with_stdio(false);

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

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.

Why ios::sync_with_studio(0) and cin.tie(0); doesn't work with strings in C++

That's the way it is. You need to make sure that you're writing the names correctly. You can always take a look at https://en.cppreference.com/w/.

But in this case, check this: std::ios_base::sync_with_stdio

Also keep in mind that if set to false, the C++ standard stream objects such as cout, clog, cerr, wcout, etc. will not be synchronized and you might see unexpectedly interleaved output if you mix them.



Related Topics



Leave a reply



Submit