[PATCH 5/5] include: Fix conflicting definitions of NULL, wchar_t, wint_t, wctype_t.

Puetz Kevin A PuetzKevinA at JohnDeere.com
Wed Jul 22 08:35:41 CDT 2020

> -----Original Message-----
> From: Jacek Caban <jacek at codeweavers.com>
> Sent: Wednesday, July 22, 2020 7:35 AM
> To: Puetz Kevin A <PuetzKevinA at JohnDeere.com>; wine-devel <wine-
> devel at winehq.org>
> Subject: Re: [PATCH 5/5] include: Fix conflicting definitions of NULL, wchar_t,
> wint_t, wctype_t.
> Hi Kevin,
> On 17.07.2020 03:12, Puetz Kevin A wrote:
> > When <basetyps.h> defines wchar_t, it must obey -f(no-)short-wchar by
> > referring to __WCHAR_TYPE__ which may not be `unsigned short`.
> > Similarly, windef.h defining NULL may need to use GCC's __null.
> > Otherwise one-definition-rule problems arise depending on whether wine
> > or libc headers are included first.
> >
> > Implementing these by deferring to the C89-specified libc headers, (or
> > msvcrt's versions with -mno-cygwin) ensures matching definitions.
> This seems to be indeed the most compatible way. It looks like __need_*
> macros widely supported (not only by GCC itself, but also versions provided
> by mingw and LLVM). We may want to support that in our msvcrt headers, if
> we start using it.

That would be a little tricky because wine's MSVCRT delegates most of stddef.h 
into corecrt.h. I guess one could extend the __need_* guards into corecrt.h too,
but it'll get messy.

> However, it's not supported by MSVC. The fallback should still work, as you
> explained, but I wonder if it would be safer to guard stddef.h usage by
> defined(__GNUC__) and leave existing definitions for other configurations.

I think if anything, I'd rather do the opposite - check _MSC_VER and give it 
what a definition we hope matches the Windows SDK, deferring to 
<stddef.h> for portability on other compilers.

But I don't think this actually makes a lot of sense either. Windows SDK 10.0.17763.0
drags in windef.h -> minwindef.h -> winnt.h -> ctype.h -> corecrt.h,
and also  winnt.h -> guiddef.h -> string.h. By the end you're only avoiding 
__threadid(), __threadhandle(), offsetof(), and (for c++) std::nullptr_t,
the rest of corecrt.h gets pulled in eventually anyway.

And it looks like wine's winnt.h actually even includes stddef.h too
(except for RC_INVOKED, which I also special-cased). So the state *after*
windef.h is complete already has everything, it's just (currently) has a weird
NULL for a while in the middle, and a potentially conflicting wchar_t.

> Please avoid C++ style comments. Wine uses /* */ comments.

Oops, fixed.

More information about the wine-devel mailing list