The return of UTF-8 is an obvious choice. If an application using your exceptions uses a different multibyte encoding, it may be difficult to display the string. (He can't know this UTF-8, right?) On the other hand, for ISO-8859- * 8-bit encodings (Western European, Cyrillic, etc.) Displaying the UTF-8 string will be "simple" some gibberish is displayed, and you (or your user) may be ok with this if you cannot disambiguate by the way. a char * in the locale and UTF-8 character set.
Personally, I think that only low-level error messages should appear on lines () and personally, I think they should be English. (Perhaps combined with some errors or something else.)
The worst problem that I see with what() is that the what () message, for example, the file name, often includes some contextual data. File names are not ASCII quite often, so you have no choice but to use UTF-8 as the encoding what() .
Note also that your exception class (derived from std :: exception) can obviously provide any access methods you like, and therefore it makes sense to add explicit what_utf8() or what_utf16() or what_iso8859_5() .
Edit: Regarding John's comment on how to return UTF-8:
If you have a const char* what() function, this function essentially returns a bunch of bytes. On the Western European Windows platform, these bytes are usually encoded as Win1252 , but in Russian windows there can also be Win1251 .
What the bytes mean depends on their encoding, and their encoding depends on where they came from (and who interprets them). String literal encoding is determined at compile time, but at runtime it still depends on the application how to interpret them.
So for your exception to return UTF-8 strings with what() (or what_utf8() ), you must make sure that:
- The input message for your exception has a well-defined encoding
- You have a well-defined encoding for the string member that you use to store the message.
- You convert the encoding accordingly when
what() is called
Example:
struct MyExc : virtual public std::exception { MyExc(const char* msg) : exception(msg) { } std::string what_utf8() { return convert_iso8859_1_to_utf8( what() ); } };
The conversion can also be placed in the (overridden) function what () of the MyExc () member or you can throw an exception to take an already encoded UTF-8 string or you could convert (from the expected input encoding, possibly wchar_t / UTF-16) to ctor.