See following program which requires the first "fwide" so as to allow "std::cout" to work after "std::wcout" calls. This behavior is only with GCC library and MSVC latest can comment the first "fwide" out. This indicates a bug in implementation of GCC stdlib. #include <cwchar> #include <iostream> #include <ostream> #include <cstdio> int main() { //std::fwide(stdout, -1); // you cannot comment out this line for GCC!!! std::wcout << L"This is a wide line from local wcout." << std::endl; std::fwide(stdout, -1); std::cout << "This is a narrow line after wide output." << std::endl; return 0; } In GCC family, only "std::wcout" prints while "std::cout" fails to print because stdout is still wide oriented. This can be confirmed by a test "fwide(stdout, 0) > 0" after "std::wcout" prints. See www.godbolt.org at https://www.godbolt.org/z/63Gh3xGMh
I think using fwide that way leads to undefined behaviour though. The C standard says: "Byte input/output functions shall not be applied to a wide-oriented stream and wide character input/output functions shall not be applied to a byte-oriented stream." So once the stdout stream is byte-oriented, using std::wcout is undefined. And once it's wide-oriented, using std::cout is undefined. POSIX is clear: "If the orientation of the stream has already been determined, fwide() shall not change it."
The C standard says that in a footnote for fwide: "If the orientation of the stream has already been determined, fwide does not change it." We would need to use freopen to reopen stdout so that it becomes unoriented again, but checking the current orientiation with fwide and then reopening if needed would make every operation on std::cout and std::wcout (and std::cerr, std::wcerr, std::clog and std::wclog) considerably more expensive.
And the C++ standard does not say anything about doing that, implying that the libstdc++ behaviour is expected. Using std::cout makes stdout byte-oriented, and using std::wcout makes it wide-oriented, and then it doesn't change.
It looks like libc++ uses codecvt to convert wide strings to narrow and then always uses byte-oriented I/O on the standard streams.
I guess you are right about using freopen+fwide to change orientation. Here is also what I learned from this comment (https://stackoverflow.com/a/22950466). Actually I am pretty happy with this strange workaround to switch/mix narrow and wide output as long as it works. (https://www.godbolt.org/z/6frxhTovn) It is only the first call of fwide at very beginning is giving a fishy of bug. Why does MSVC work without this strange call?
Maybe they do the same as libc++ and convert all wide strings to narrow before writing to a byte-oriented stream, or vice versa. Or maybe they don't use stdio for std::cout at all.