Another option would be using __CHAR16_TYPE__, though that's gcc-
specific.
I originally had a version of "include: Fix conflicting definitions of wchar_t..." that used __WCHAR_TYPE__ in this fashion, before I settled on using <stddef.h> as a more portable solution and a path to also fixing my other ODR issue with NULL (e.g. windef.h's 0 is 32-bit, gcc <stddef.h> uses
__null, which can be a 64-bit type).
I would prefer to make WINE_UNICODE_CHAR16 a no-op here, yes. I think that ideally we would keep it as simple as possible and try to avoid having differences between WINE_UNICODE_CHAR16 and non-WINE_UNICODE_CHAR16 to minimum. Those few typedefs are all places in Wine that need to be aware of char16_t, all other places may just use WCHAR. A new include with a new type that's not really needed for Wine headers has bigger impact on compiled code than we need. I'd prefer to avoid it.
Ok, it's messier, but I can live with that. I just figured wine itself never set WINE_UNICODE_CHAR16, and anyone's project that did would be unsurprised to now get the definitions of <uchar.h>, so it was the "obviously correct" path instead of the "reverse engineer libc and match it".
I'm not sure why you mention a problem with TEXT macro. Current solution from winnt.rh uses u"" always when WINE_UNICODE_NATIVE is not used, so it's used in WINE_UNICODE_CHAR16 case as well. While it could be possible to try harder to make sure that it's supported by compiler, where is not much we can do about it. I don't see any fallback we could use in such case, so we may as well just let compiler fail to parse code that uses it in such case.
My issue was that I could easily have a compiler which does support u"", but a project that did not set WINE_UNICODE_CHAR16. In which TEXT() compiles, but has type char16_t[], not WCHAR[]. With overloading, templates, or auto, the eventual mismatch error can be quite distant from the offending TEXT().
This isn't such an issue for C, since char16_t=unsigned short anyway so it will probably work out.
I would also be perfectly happy to make this even simpler and just make char16_t consistent, e.g. WINE_UNICODE_NATIVE -> wchar_t and L"", else char16_t and u"". for C and pre-C++11 where it isn't already a fundamental type, Wine would follow GCC's __CHAR16_TYPE__ (thus matching <uchar.h>) or just use unsigned short (which is in practice what __CHAR16_TYPE__ will be anyway).
#ifdef WINE_UNICODE_NATIVE typdef wchar_t WCHAR; #define TEXT(x) L ## x #else #ifndef __cpp_unicode_characters #ifdef __CHAR16_TYPE__ typedef __CHAR16_TYPE__ char16_t; #else typedef unsigned short char16_t; #endif typedef char16_t WCHAR; #define TEXT(x) u ## x #endif
That could be an ABI breaking change for C++11 winelib programs since WCHAR in functions that aren't extern "C" would now name-mangle char16_t. But it doesn't change anything for C (or for C++03). I don't know to what extent wine makes winelib ABI promises, and I guess in any case wine 5->6 will be a major version. Maybe it's OK? It's certainly tidier... only 2 choices, and just controlled by -f(no-)short-wchar.
Thanks,
Jacek