3

I recently learned something from this question about cin in C++ and its speed was compared with the speed of scanf in C. Calling cin object is much slower than calling scanf function as usual but when I was reading the accepted answer, I understood if we call std::ios::sync_with_stdio(false);, cin synchronization with scanf is turned off and cin speed becomes so faster and even faster than scanf in this case.

So, will we face some problems if we turn it off? If so, what problems, and is it good to turn off cin synchronization with scanf in C? Thanks for helping.

2 Answers2

7

If you use both sets of I/O functions (header <cstdio> or <stdio.h> and also <iostream>) on the same stream (e.g. the stdin stream is associated with both scanf and cin), then you'd better leave them synchronized.

If any one stream only uses one I/O family you can turn off synchronization (you can still use fscanf with a particular file and cin with stdin for example, as long as separate streams are involved).

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • Is it still necessary to manually turn off synchronization if you don't mix C and C++ I/O? It seems like a weird exception to C++'s "fast by default" philosophy. One would expect performance-pessimizing synchronization to be opt-in. – Nathan Pierson Feb 05 '21 at 19:34
  • 5
    @NathanPierson: Backward compatibility is a bigger goal than fast-by-default. It seems more worthwhile to share buffers in an efficient manner where the synchronization cost goes away, than it does to try to disable synchronization by default. – Ben Voigt Feb 05 '21 at 19:36
  • @NathanPierson: The primary time you'd want to turn off synchronization is exactly that--when you're not mixing the two at all. Careful use of weak external symbols would probably let you automate unsynchronized access if the program didn't use any C-style I/O at all though. – Jerry Coffin Feb 05 '21 at 20:09
  • @JerryCoffin: That can't work on any system that supports (a) dynamic loading and (b) shared libraries for the C and C++ standard library, because the program can dynamically load a new library that uses the C API at any time, including after iostreams has started buffering data. – Ben Voigt Feb 05 '21 at 20:17
  • @BenVoigt: Yeah, dealing with that would be tricky, at best. I'd have to think about it bit to be at all sure, but my immediate reaction is that I'm not *entirely* convinced it couldn't be handled as well (but it would definitely take more than what I was contemplating). – Jerry Coffin Feb 05 '21 at 20:55
  • @JerryCoffin: It seems far easier to build a unified buffering layer than stdio and iostreams can share, that supports the union of whatever features (block-get and unget) both use, so that there's no penalty for synchronization. – Ben Voigt Feb 05 '21 at 21:41
  • @BenVoigt: Could well be. – Jerry Coffin Feb 05 '21 at 23:06
4

Basically problem can manifest when C API is used at the same time. Many strange artifacts can appear: missing data, wrong order, unexpected error.

It is possible you have full control over full code stack and you can ensure that C API is not used.

Sadly usually your application uses third party libraries. One of them can use C API to output some data to stream (especially if one of them is C library). Since you do not control third party library behavior, synchronization is required.

Marek R
  • 32,568
  • 6
  • 55
  • 140