Mixing Cout and Wcout in Same Program

Mixing cout and wcout in same program

When cout or wcout is called for the first time, the orientation for stdout becomes set. In the case of cout, stdout becomes a byte-oriented stream, and in the case of wcout, stdout becomes a wide-oriented stream. Per the C++ standard [27.4.1] and C standard [7.19.2], once the orientation of a stream is set, you should not call a function which is not compatible with the orientation of that stream.

strange behaviour of this c++ piece of code (std::wcout and std::exception)

Your example does not prove the exception wasn't thrown.

The cout message in your catch block is not displayed, because you already used wcout and mixing character widths on the same device (stdout) is Undefined Behaviour.

Change the cout to wcout and you'll see the exception was thrown, you just didn't see the message you expected.

How does wcout work?

This example invokes undefined behavior.

operator<<(std::wostream&,const wchar_t*) expects the buffer to be null terminated, and stop printing characters when it reaches the first L'\0' character. If the buffer happens to contain a null character (L'\0'), then the code will run "correctly" (although the output is unpredictable). If it doesn't, then operator<< will keep reading the memory until it encounters one.

The presence of a null terminator is not enforced by your example. In comparison, the following would print an unspecified number of characters, most likely junk, but is well defined:

WCHAR wArray[1024];
wArray[1023] = L'\0';
wcout << wArray << endl;

Mixing cout and wcout in same program

When cout or wcout is called for the first time, the orientation for stdout becomes set. In the case of cout, stdout becomes a byte-oriented stream, and in the case of wcout, stdout becomes a wide-oriented stream. Per the C++ standard [27.4.1] and C standard [7.19.2], once the orientation of a stream is set, you should not call a function which is not compatible with the orientation of that stream.

Confusion about wcout and cout, wstring and string

The problem is that you're storing a std::wstring regardless of whether the template type T is char or wchar_t. Instead, you want to use the template std::basic_string with the appropriate type:

std::basic_string<T> *data;

std::string is just a typedef for std::basic_string<char>, and std::wstring is just a typedef for std::basic_string<wchar_t>.

Similarly, std::ostream is just a typedef for std::basic_ostream<char>, and std::wostream is just a typedef for std::basic_ostream<wchar_t>, so you could have a single print function that takes a std::basic_ostream templated on the appropriate type.



Related Topics



Leave a reply



Submit