[PATCH 1/5] include: Fix undefined char16_t with -DWINE_UNICODE_CHAR16.

Puetz Kevin A PuetzKevinA at JohnDeere.com
Tue Jul 21 13:31:26 CDT 2020

> > 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).

typdef wchar_t WCHAR;
#define TEXT(x) L ## x
#ifndef __cpp_unicode_characters
#ifdef __CHAR16_TYPE__
typedef __CHAR16_TYPE__ char16_t;
typedef unsigned short char16_t;
typedef char16_t WCHAR;
#define TEXT(x) u ## x

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

More information about the wine-devel mailing list