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
# endif
#endif // Py_GIL_DISABLED
+#ifdef _MSC_VER
+// Ignore MSC warning C4201: "nonstandard extension used: nameless
+// struct/union". (Only generated for C standard versions less than C11, which
+// we don't *officially* support.)
+__pragma(warning(push))
+__pragma(warning(disable: 4201))
+#endif
+
+
// Include Python header files
#include "pyport.h"
#include "pymacro.h"
#include "cpython/pyfpe.h"
#include "cpython/tracemalloc.h"
+#ifdef _MSC_VER
+__pragma(warning(pop)) // warning(disable: 4201)
+#endif
+
#endif /* !Py_PYTHON_H */
/* 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 {
#endif
_Py_ALIGNED_DEF(_PyObject_MIN_ALIGNMENT, char) _aligner;
};
-#ifdef _MSC_VER
- __pragma(warning(pop))
-#endif
PyTypeObject *ob_type;
};
# endif
#endif
+
+// _Py_ANONYMOUS: modifier for declaring an anonymous union.
+// Usage: _Py_ANONYMOUS union { ... };
+// Standards/compiler support:
+// - C++ allows anonymous unions, but not structs
+// - C11 and above allows anonymous unions and structs
+// - MSVC has warning(disable: 4201) "nonstandard extension used : nameless
+// struct/union". This is specific enough that we disable it for all of
+// Python.h.
+// - GCC & clang needs __extension__ before C11
+// To allow unsupported platforms which need other spellings, we use a
+// predefined value of _Py_ANONYMOUS if it exists.
+#ifndef _Py_ANONYMOUS
+# if (defined(__GNUC__) || defined(__clang__)) \
+ && !(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L)
+# define _Py_ANONYMOUS __extension__
+# else
+# define _Py_ANONYMOUS
+# endif
+#endif
+
+
/* Minimum value between x and y */
#define Py_MIN(x, y) (((x) > (y)) ? (y) : (x))