port(stddef shim): Windows keeps the stub; Linux/macOS use GCC builtins

The first cut routed C TUs to hoststddef.h unconditionally. That regresses
MinGW: its <stddef.h> defines `errno (*_errno())`, which collides with
PR/os.h's `u8 errno;` field. And hoststddef.h's bin/../include/stddef.h path
does not exist on Linux anyway.

Split three ways: C++ -> hoststddef.h (unchanged); C on Windows -> the empty
N64 stub (unchanged, pre-existing behaviour); C on Linux/macOS -> size_t /
ptrdiff_t / NULL / offsetof from __SIZE_TYPE__ / __PTRDIFF_TYPE__ /
__builtin_offsetof (always predefined, no header, no collision).

Verified: Windows ntsc-final builds 240/240, -level_09 boots crash-free.
This commit is contained in:
James Dansereau committed 2026-09-02 21:24:43 -04:00
1 parent 01fd39a089
commit a8c5652dac
1 file changed
+26 -8
+26 -8
View File
@@ -25,15 +25,33 @@
#undef __need_NULL
#undef __need_wint_t
#include "hoststddef.h"
#elif defined(_WIN32)
/*
* C TUs on MinGW: keep the empty N64 include/stddef.h stub. MinGW's CRT
* headers leak size_t/ptrdiff_t transitively, and its own <stddef.h> drags in
* the `#define errno (*_errno())` CRT macro, which collides with PR/os.h's
* `u8 errno;` struct field — so routing to the host header is not an option
* here.
*/
#include "include/stddef.h"
#else
/*
* C TUs: the N64 include/stddef.h is an empty stub (its active body defines
* neither size_t nor ptrdiff_t nor NULL). MinGW leaked those in transitively
* through its CRT headers, so the stub was harmless there; glibc/GCC defines
* them ONLY in the compiler's own <stddef.h>, so a C TU on Linux that relies
* on <stddef.h> (e.g. include/PR/ultratypes.h's non-N64 path) fails to
* compile. Route C TUs to the host header too — purely additive, the active
* N64 stub typedefs nothing that could clash.
* C TUs on Linux/macOS: the N64 include/stddef.h stub defines nothing, glibc
* only defines these in the compiler's shadowed builtin <stddef.h>, and the
* MinGW hoststddef trick (bin/../include/stddef.h) does not exist on Linux.
* Provide the standard types straight from the always-predefined GCC/Clang
* builtins — no header, so nothing to collide with. C11 permits the benign
* identical redefinition if a real <stddef.h> is ever reached another way.
*/
#include "hoststddef.h"
#ifndef _PORT_SHIM_STDDEF_TYPES
#define _PORT_SHIM_STDDEF_TYPES
typedef __SIZE_TYPE__ size_t;
typedef __PTRDIFF_TYPE__ ptrdiff_t;
#ifndef NULL
#define NULL ((void *)0)
#endif
#ifndef offsetof
#define offsetof(t, m) __builtin_offsetof(t, m)
#endif
#endif
#endif