Consider this code:
#include <iostream>
using namespace std;
int main () {
ios::sync_with_stdio(false);
ios::sync_with_stdio(true);
}
In GCC, are the C++ streams like std::cout etc then synchronized with the corresponding C methods like printf?
Answer
No — the second sync_with_stdio has no effect at all.
There is no trick here: the booleans aren't being interpreted as pointers or anything like that. There is simply no code to handle turning synchronization back on.
Implementation of sync_with_stdio
bool
ios_base::sync_with_stdio(bool __sync)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 49. Underspecification of ios_base::sync_with_stdio
bool __ret = ios_base::Init::_S_synced_with_stdio;
// Turn off sync with C FILE* for cin, cout, cerr, clog iff
// currently synchronized.
if (!__sync && __ret)
{
// Make sure the standard streams are constructed.
ios_base::Init __init;
ios_base::Init::_S_synced_with_stdio = __sync;
// Explicitly call dtors to free any memory that is
// dynamically allocated by filebuf ctor or member functions,
// but don't deallocate all memory by calling operator delete.
buf_cout_sync.~stdio_sync_filebuf<char>();
buf_cin_sync.~stdio_sync_filebuf<char>();
buf_cerr_sync.~stdio_sync_filebuf<char>();
#ifdef _GLIBCXX_USE_WCHAR_T
buf_wcout_sync.~stdio_sync_filebuf<wchar_t>();
buf_wcin_sync.~stdio_sync_filebuf<wchar_t>();
buf_wcerr_sync.~stdio_sync_filebuf<wchar_t>();
#endif
// Create stream buffers for the standard streams and use
// those buffers without destroying and recreating the
// streams.
new (&buf_cout) stdio_filebuf<char>(stdout, ios_base::out);
new (&buf_cin) stdio_filebuf<char>(stdin, ios_base::in);
new (&buf_cerr) stdio_filebuf<char>(stderr, ios_base::out);
cout.rdbuf(&buf_cout);
cin.rdbuf(&buf_cin);
cerr.rdbuf(&buf_cerr);
clog.rdbuf(&buf_cerr);
#ifdef _GLIBCXX_USE_WCHAR_T
new (&buf_wcout) stdio_filebuf<wchar_t>(stdout, ios_base::out);
new (&buf_wcin) stdio_filebuf<wchar_t>(stdin, ios_base::in);
new (&buf_wcerr) stdio_filebuf<wchar_t>(stderr, ios_base::out);
wcout.rdbuf(&buf_wcout);
wcin.rdbuf(&buf_wcin);
wcerr.rdbuf(&buf_wcerr);
wclog.rdbuf(&buf_wcerr);
#endif
}
return __ret;
}








Is this behavior the same across all compiler?
or just unique to GCC?
is it specified on the C++ standard?
Why am I not checking it myself instead of asking questions? Cause I don't know where to check.
When in doubt, consult an eel.
Calling with
trueis left to implementation. I suspect the reason is that resyncing what was made out of sync is a complicated topic.So it feels like more of a "config" than "function"
I wonder why the C++ committee didn't do something like
ios::desync_from_stdio()(without arguments), because theboolargument is really not needed.Because it doesn't really matter. You either allow resync to be implemented as part of existing interface but don't force it, or you allow resync to be implemented as an extra function within a namespace (a standard library implementation is allowed to add stuff, just users aren't) but don't force it. As software design decisions go, this one isn't worth focusing on.