-----Original Message----- From: Jacek Caban jacek@codeweavers.com Sent: Wednesday, July 22, 2020 7:35 AM To: Puetz Kevin A PuetzKevinA@JohnDeere.com; wine-devel <wine- devel@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.