gh-138143: Allow anonymous unions in public headers, using _Py_ANONYMOUS (GH-137283)

We already use an anonymous union for PyObject. This makes the workarounds available in all public headers:

- MSVC: `__pragma(warning(disable: 4201))` (with push/pop). Warning 4201 is specifically for anonymous unions, so let's disable for all of `<Python.h>`
- GCC/clang, pedantic old C standards: define `_Py_ANONYMOUS` as `__extension__`
- otherwise, define `_Py_ANONYMOUS` as nothing 

(Note that this is only for public headers -- CPython internals use C11, which has anonymous structs/unions.)

C API WG vote: https://github.com/capi-workgroup/decisions/issues/74
This commit is contained in:
Petr Viktorin 2025-08-26 11:14:35 +02:00 committed by GitHub
parent 73fb155ba7
commit ce1a877a38
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 36 additions and 15 deletions

View file

@ -123,18 +123,7 @@ whose size is determined when the object is allocated.
/* PyObject is opaque */
#elif !defined(Py_GIL_DISABLED)
struct _object {
#if (defined(__GNUC__) || defined(__clang__)) \
&& !(defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L)
// On C99 and older, anonymous union is a GCC and clang extension
__extension__
#endif
#ifdef _MSC_VER
// Ignore MSC warning C4201: "nonstandard extension used:
// nameless struct/union"
__pragma(warning(push))
__pragma(warning(disable: 4201))
#endif
union {
_Py_ANONYMOUS union {
#if SIZEOF_VOID_P > 4
PY_INT64_T ob_refcnt_full; /* This field is needed for efficient initialization with Clang on ARM */
struct {
@ -153,9 +142,6 @@ struct _object {
#endif
_Py_ALIGNED_DEF(_PyObject_MIN_ALIGNMENT, char) _aligner;
};
#ifdef _MSC_VER
__pragma(warning(pop))
#endif
PyTypeObject *ob_type;
};