https://github.com/python/cpython/commit/3fe97357ce5508f903a9022d7f0392d159a0ee77
commit: 3fe97357ce5508f903a9022d7f0392d159a0ee77
branch: 3.14
author: Miss Islington (bot) <[email protected]>
committer: encukou <[email protected]>
date: 2026-02-06T12:50:06+01:00
summary:

[3.14] gh-141004: Reorganize and reword the 'Useful macros' section (GH-144471) 
(GH-144541)

- Group the macros
- Roughly order them to put the most important ones first
- Add expansions where it makes sense; especially if there's
  an equivalent in modern C or a common compiler

(cherry picked from commit f85e1170d2b22d2ee42cd568144e0c9f57b0db67)

Co-authored-by: Petr Viktorin <[email protected]>
Co-authored-by: Victor Stinner <[email protected]>
Co-authored-by: Peter Bierma <[email protected]>

files:
M Doc/c-api/intro.rst

diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst
index 3cd14e4e7be293..dcccc8b6493eb7 100644
--- a/Doc/c-api/intro.rst
+++ b/Doc/c-api/intro.rst
@@ -116,68 +116,6 @@ defined closer to where they are useful (for example, 
:c:macro:`Py_RETURN_NONE`,
 Others of a more general utility are defined here.  This is not necessarily a
 complete listing.
 
-
-.. c:macro:: Py_ABS(x)
-
-   Return the absolute value of ``x``.
-
-   If the result cannot be represented (for example, if ``x`` has
-   :c:macro:`!INT_MIN` value for :c:expr:`int` type), the behavior is
-   undefined.
-
-   .. versionadded:: 3.3
-
-.. c:macro:: Py_ALIGNED(num)
-
-   Specify alignment to *num* bytes on compilers that support it.
-
-   Consider using the C11 standard ``_Alignas`` specifier over this macro.
-
-.. c:macro:: Py_ARITHMETIC_RIGHT_SHIFT(type, integer, positions)
-
-   Similar to ``integer >> positions``, but forces sign extension, as the C
-   standard does not define whether a right-shift of a signed integer will
-   perform sign extension or a zero-fill.
-
-   *integer* should be any signed integer type.
-   *positions* is the number of positions to shift to the right.
-
-   Both *integer* and *positions* can be evaluated more than once;
-   consequently, avoid directly passing a function call or some other
-   operation with side-effects to this macro. Instead, store the result as a
-   variable and then pass it.
-
-   *type* is unused and only kept for backwards compatibility. Historically,
-   *type* was used to cast *integer*.
-
-   .. versionchanged:: 3.1
-
-      This macro is now valid for all signed integer types, not just those for
-      which ``unsigned type`` is legal. As a result, *type* is no longer
-      used.
-
-.. c:macro:: Py_ALWAYS_INLINE
-
-   Ask the compiler to always inline a static inline function. The compiler can
-   ignore it and decide to not inline the function.
-
-   It can be used to inline performance critical static inline functions when
-   building Python in debug mode with function inlining disabled. For example,
-   MSC disables function inlining when building in debug mode.
-
-   Marking blindly a static inline function with Py_ALWAYS_INLINE can result in
-   worse performances (due to increased code size for example). The compiler is
-   usually smarter than the developer for the cost/benefit analysis.
-
-   If Python is :ref:`built in debug mode <debug-build>` (if the 
:c:macro:`Py_DEBUG`
-   macro is defined), the :c:macro:`Py_ALWAYS_INLINE` macro does nothing.
-
-   It must be specified before the function return type. Usage::
-
-       static inline Py_ALWAYS_INLINE int random(void) { return 4; }
-
-   .. versionadded:: 3.11
-
 .. c:macro:: Py_CAN_START_THREADS
 
    If this macro is defined, then the current system is able to start threads.
@@ -187,139 +125,143 @@ complete listing.
 
    .. versionadded:: 3.13
 
-.. c:macro:: Py_CHARMASK(c)
-
-   Argument must be a character or an integer in the range [-128, 127] or [0,
-   255].  This macro returns ``c`` cast to an ``unsigned char``.
-
-.. c:macro:: Py_DEPRECATED(version)
+.. c:macro:: Py_GETENV(s)
 
-   Use this for deprecated declarations.  The macro must be placed before the
-   symbol name.
+   Like :samp:`getenv({s})`, but returns ``NULL`` if :option:`-E` was passed
+   on the command line (see :c:member:`PyConfig.use_environment`).
 
-   Example::
 
-      Py_DEPRECATED(3.8) PyAPI_FUNC(int) Py_OldFunction(void);
+Docstring macros
+----------------
 
-   .. versionchanged:: 3.8
-      MSVC support was added.
+.. c:macro:: PyDoc_STRVAR(name, str)
 
-.. c:macro:: Py_FORCE_EXPANSION(X)
+   Creates a variable with name *name* that can be used in docstrings.
+   If Python is built without docstrings (:option:`--without-doc-strings`),
+   the value will be an empty string.
 
-   This is equivalent to ``X``, which is useful for token-pasting in
-   macros, as macro expansions in *X* are forcefully evaluated by the
-   preprocessor.
+   Example::
 
-.. c:macro:: Py_GCC_ATTRIBUTE(name)
+      PyDoc_STRVAR(pop_doc, "Remove and return the rightmost element.");
 
-   Use a GCC attribute *name*, hiding it from compilers that don't support GCC
-   attributes (such as MSVC).
+      static PyMethodDef deque_methods[] = {
+          // ...
+          {"pop", (PyCFunction)deque_pop, METH_NOARGS, pop_doc},
+          // ...
+      }
 
-   This expands to ``__attribute__((name))`` on a GCC compiler, and expands
-   to nothing on compilers that don't support GCC attributes.
+   Expands to :samp:`PyDoc_VAR({name}) = PyDoc_STR({str})`.
 
-.. c:macro:: Py_GETENV(s)
+.. c:macro:: PyDoc_STR(str)
 
-   Like ``getenv(s)``, but returns ``NULL`` if :option:`-E` was passed on the
-   command line (see :c:member:`PyConfig.use_environment`).
+   Expands to the given input string, or an empty string
+   if docstrings are disabled (:option:`--without-doc-strings`).
 
-.. c:macro:: Py_LL(number)
+   Example::
 
-   Use *number* as a ``long long`` integer literal.
+      static PyMethodDef pysqlite_row_methods[] = {
+          {"keys", (PyCFunction)pysqlite_row_keys, METH_NOARGS,
+              PyDoc_STR("Returns the keys of the row.")},
+          {NULL, NULL}
+      };
 
-   This usally expands to *number* followed by ``LL``, but will expand to some
-   compiler-specific suffixes (such as ``I64``) on older compilers.
+.. c:macro:: PyDoc_VAR(name)
 
-   In modern versions of Python, this macro is not very useful, as C99 and
-   later require the ``LL`` suffix to be valid for an integer.
+   Declares a static character array variable with the given *name*.
+   Expands to :samp:`static const char {name}[]`
 
-.. c:macro:: Py_LOCAL(type)
+   For example::
 
-   Declare a function returning the specified *type* using a fast-calling
-   qualifier for functions that are local to the current file.
-   Semantically, this is equivalent to ``static type``.
+      PyDoc_VAR(python_doc) = PyDoc_STR(
+         "A genus of constricting snakes in the Pythonidae family native "
+         "to the tropics and subtropics of the Eastern Hemisphere.");
 
-.. c:macro:: Py_LOCAL_INLINE(type)
 
-   Equivalent to :c:macro:`Py_LOCAL` but additionally requests the function
-   be inlined.
+General utility macros
+----------------------
 
-.. c:macro:: Py_LOCAL_SYMBOL
+The following macros common tasks not specific to Python.
 
-   Macro used to declare a symbol as local to the shared library (hidden).
-   On supported platforms, it ensures the symbol is not exported.
+.. c:macro:: Py_UNUSED(arg)
 
-   On compatible versions of GCC/Clang, it
-   expands to ``__attribute__((visibility("hidden")))``.
+   Use this for unused arguments in a function definition to silence compiler
+   warnings. Example: ``int func(int a, int Py_UNUSED(b)) { return a; }``.
 
-.. c:macro:: Py_MAX(x, y)
+   .. versionadded:: 3.4
 
-   Return the maximum value between ``x`` and ``y``.
+.. c:macro:: Py_GCC_ATTRIBUTE(name)
 
-   .. versionadded:: 3.3
+   Use a GCC attribute *name*, hiding it from compilers that don't support GCC
+   attributes (such as MSVC).
 
-.. c:macro:: Py_MEMBER_SIZE(type, member)
+   This expands to :samp:`__attribute__(({name)})` on a GCC compiler,
+   and expands to nothing on compilers that don't support GCC attributes.
 
-   Return the size of a structure (``type``) ``member`` in bytes.
 
-   .. versionadded:: 3.6
+Numeric utilities
+^^^^^^^^^^^^^^^^^
 
-.. c:macro:: Py_MEMCPY(dest, src, n)
+.. c:macro:: Py_ABS(x)
 
-   This is a :term:`soft deprecated` alias to :c:func:`!memcpy`.
-   Use :c:func:`!memcpy` directly instead.
+   Return the absolute value of ``x``.
 
-   .. deprecated:: 3.14
-      The macro is :term:`soft deprecated`.
+   The argument may be evaluated more than once.
+   Consequently, do not pass an expression with side-effects directly
+   to this macro.
 
-.. c:macro:: Py_MIN(x, y)
+   If the result cannot be represented (for example, if ``x`` has
+   :c:macro:`!INT_MIN` value for :c:expr:`int` type), the behavior is
+   undefined.
 
-   Return the minimum value between ``x`` and ``y``.
+   Corresponds roughly to :samp:`(({x}) < 0 ? -({x}) : ({x}))`
 
    .. versionadded:: 3.3
 
-.. c:macro:: Py_NO_INLINE
+.. c:macro:: Py_MAX(x, y)
+             Py_MIN(x, y)
 
-   Disable inlining on a function. For example, it reduces the C stack
-   consumption: useful on LTO+PGO builds which heavily inline code (see
-   :issue:`33720`).
+   Return the larger or smaller of the arguments, respectively.
 
-   Usage::
+   Any arguments may be evaluated more than once.
+   Consequently, do not pass an expression with side-effects directly
+   to this macro.
 
-       Py_NO_INLINE static int random(void) { return 4; }
+   :c:macro:`!Py_MAX` corresponds roughly to
+   :samp:`((({x}) > ({y})) ? ({x}) : ({y}))`.
 
-   .. versionadded:: 3.11
+   .. versionadded:: 3.3
 
-.. c:macro:: Py_SAFE_DOWNCAST(value, larger, smaller)
+.. c:macro:: Py_ARITHMETIC_RIGHT_SHIFT(type, integer, positions)
 
-   Cast *value* to type *smaller* from type *larger*, validating that no
-   information was lost.
+   Similar to :samp:`{integer} >> {positions}`, but forces sign extension,
+   as the C standard does not define whether a right-shift of a signed
+   integer will perform sign extension or a zero-fill.
 
-   On release builds of Python, this is roughly equivalent to
-   ``(smaller) value`` (in C++, ``static_cast<smaller>(value)`` will be
-   used instead).
+   *integer* should be any signed integer type.
+   *positions* is the number of positions to shift to the right.
 
-   On debug builds (implying that :c:macro:`Py_DEBUG` is defined), this asserts
-   that no information was lost with the cast from *larger* to *smaller*.
+   Both *integer* and *positions* can be evaluated more than once;
+   consequently, avoid directly passing a function call or some other
+   operation with side-effects to this macro. Instead, store the result as a
+   variable and then pass it.
 
-   *value*, *larger*, and *smaller* may all be evaluated more than once in the
-   expression; consequently, do not pass an expression with side-effects 
directly to
-   this macro.
+   *type* is unused and only kept for backwards compatibility. Historically,
+   *type* was used to cast *integer*.
 
-.. c:macro:: Py_STRINGIFY(x)
+   .. versionchanged:: 3.1
 
-   Convert ``x`` to a C string.  E.g. ``Py_STRINGIFY(123)`` returns
-   ``"123"``.
+      This macro is now valid for all signed integer types, not just those for
+      which ``unsigned type`` is legal. As a result, *type* is no longer
+      used.
 
-   .. versionadded:: 3.4
+.. c:macro:: Py_CHARMASK(c)
 
-.. c:macro:: Py_ULL(number)
+   Argument must be a character or an integer in the range [-128, 127] or [0,
+   255].  This macro returns ``c`` cast to an ``unsigned char``.
 
-   Similar to :c:macro:`Py_LL`, but *number* will be an ``unsigned long long``
-   literal instead. This is done by appending ``U`` to the result of ``Py_LL``.
 
-   In modern versions of Python, this macro is not very useful, as C99 and
-   later require the ``ULL``/``LLU`` suffixes to be valid for an integer.
+Assertion utilities
+^^^^^^^^^^^^^^^^^^^
 
 .. c:macro:: Py_UNREACHABLE()
 
@@ -332,8 +274,11 @@ complete listing.
    avoids a warning about unreachable code.  For example, the macro is
    implemented with ``__builtin_unreachable()`` on GCC in release mode.
 
+   In debug mode, and on unsupported compilers, the macro expands to a call to
+   :c:func:`Py_FatalError`.
+
    A use for ``Py_UNREACHABLE()`` is following a call a function that
-   never returns but that is not declared :c:macro:`_Py_NO_RETURN`.
+   never returns but that is not declared ``_Noreturn``.
 
    If a code path is very unlikely code but can be reached under exceptional
    case, this macro must not be used.  For example, under low memory condition
@@ -343,18 +288,29 @@ complete listing.
 
    .. versionadded:: 3.7
 
-.. c:macro:: Py_UNUSED(arg)
+.. c:macro:: Py_SAFE_DOWNCAST(value, larger, smaller)
 
-   Use this for unused arguments in a function definition to silence compiler
-   warnings. Example: ``int func(int a, int Py_UNUSED(b)) { return a; }``.
+   Cast *value* to type *smaller* from type *larger*, validating that no
+   information was lost.
 
-   .. versionadded:: 3.4
+   On release builds of Python, this is roughly equivalent to
+   :samp:`(({smaller}) {value})`
+   (in C++, :samp:`static_cast<{smaller}>({value})` will be used instead).
+
+   On debug builds (implying that :c:macro:`Py_DEBUG` is defined), this asserts
+   that no information was lost with the cast from *larger* to *smaller*.
+
+   *value*, *larger*, and *smaller* may all be evaluated more than once in the
+   expression; consequently, do not pass an expression with side-effects
+   directly to this macro.
 
 .. c:macro:: Py_BUILD_ASSERT(cond)
 
    Asserts a compile-time condition *cond*, as a statement.
    The build will fail if the condition is false or cannot be evaluated at 
compile time.
 
+   Corresponds roughly to :samp:`static_assert({cond})` on C23 and above.
+
    For example::
 
       Py_BUILD_ASSERT(sizeof(PyTime_t) == sizeof(int64_t));
@@ -373,62 +329,127 @@ complete listing.
 
    .. versionadded:: 3.3
 
-.. c:macro:: PyDoc_STRVAR(name, str)
 
-   Creates a variable with name *name* that can be used in docstrings.
-   If Python is built without docstrings, the value will be empty.
+Type size utilities
+^^^^^^^^^^^^^^^^^^^
 
-   Use :c:macro:`PyDoc_STRVAR` for docstrings to support building
-   Python without docstrings, as specified in :pep:`7`.
+.. c:macro:: Py_ARRAY_LENGTH(array)
 
-   Example::
+   Compute the length of a statically allocated C array at compile time.
 
-      PyDoc_STRVAR(pop_doc, "Remove and return the rightmost element.");
+   The *array* argument must be a C array with a size known at compile time.
+   Passing an array with an unknown size, such as a heap-allocated array,
+   will result in a compilation error on some compilers, or otherwise produce
+   incorrect results.
 
-      static PyMethodDef deque_methods[] = {
-          // ...
-          {"pop", (PyCFunction)deque_pop, METH_NOARGS, pop_doc},
-          // ...
-      }
+   This is roughly equivalent to::
 
-.. c:macro:: PyDoc_STR(str)
+      sizeof(array) / sizeof((array)[0])
 
-   Creates a docstring for the given input string or an empty string
-   if docstrings are disabled.
+.. c:macro:: Py_MEMBER_SIZE(type, member)
 
-   Use :c:macro:`PyDoc_STR` in specifying docstrings to support
-   building Python without docstrings, as specified in :pep:`7`.
+   Return the size of a structure (*type*) *member* in bytes.
 
-   Example::
+   Corresponds roughly to :samp:`sizeof((({type} *)NULL)->{member})`.
 
-      static PyMethodDef pysqlite_row_methods[] = {
-          {"keys", (PyCFunction)pysqlite_row_keys, METH_NOARGS,
-              PyDoc_STR("Returns the keys of the row.")},
-          {NULL, NULL}
-      };
+   .. versionadded:: 3.6
 
-.. c:macro:: PyDoc_VAR(name)
 
-   Declares a static character array variable with the given name *name*.
+Macro definition utilities
+^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-   For example::
+.. c:macro:: Py_FORCE_EXPANSION(X)
 
-      PyDoc_VAR(python_doc) = PyDoc_STR("A genus of constricting snakes in the 
Pythonidae family native "
-                                        "to the tropics and subtropics of the 
Eastern Hemisphere.");
+   This is equivalent to :samp:`{X}`, which is useful for token-pasting in
+   macros, as macro expansions in *X* are forcefully evaluated by the
+   preprocessor.
 
-.. c:macro:: Py_ARRAY_LENGTH(array)
+.. c:macro:: Py_STRINGIFY(x)
 
-   Compute the length of a statically allocated C array at compile time.
+   Convert ``x`` to a C string.  For example, ``Py_STRINGIFY(123)`` returns
+   ``"123"``.
 
-   The *array* argument must be a C array with a size known at compile time.
-   Passing an array with an unknown size, such as a heap-allocated array,
-   will result in a compilation error on some compilers, or otherwise produce
-   incorrect results.
+   .. versionadded:: 3.4
 
-   This is roughly equivalent to::
 
-      sizeof(array) / sizeof((array)[0])
+Declaration utilities
+---------------------
+
+The following macros can be used in declarations.
+They are most useful for defining the C API itself, and have limited use
+for extension authors.
+Most of them expand to compiler-specific spellings of common extensions
+to the C language.
 
+.. c:macro:: Py_ALWAYS_INLINE
+
+   Ask the compiler to always inline a static inline function. The compiler can
+   ignore it and decide to not inline the function.
+
+   Corresponds to ``always_inline`` attribute in GCC and ``__forceinline``
+   in MSVC.
+
+   It can be used to inline performance critical static inline functions when
+   building Python in debug mode with function inlining disabled. For example,
+   MSC disables function inlining when building in debug mode.
+
+   Marking blindly a static inline function with Py_ALWAYS_INLINE can result in
+   worse performances (due to increased code size for example). The compiler is
+   usually smarter than the developer for the cost/benefit analysis.
+
+   If Python is :ref:`built in debug mode <debug-build>` (if the 
:c:macro:`Py_DEBUG`
+   macro is defined), the :c:macro:`Py_ALWAYS_INLINE` macro does nothing.
+
+   It must be specified before the function return type. Usage::
+
+       static inline Py_ALWAYS_INLINE int random(void) { return 4; }
+
+   .. versionadded:: 3.11
+
+.. c:macro:: Py_NO_INLINE
+
+   Disable inlining on a function. For example, it reduces the C stack
+   consumption: useful on LTO+PGO builds which heavily inline code (see
+   :issue:`33720`).
+
+   Corresponds to the ``noinline`` attribute/specification on GCC and MSVC.
+
+   Usage::
+
+       Py_NO_INLINE static int random(void) { return 4; }
+
+   .. versionadded:: 3.11
+
+.. c:macro:: Py_DEPRECATED(version)
+
+   Use this to declare APIs that were deprecated in a specific CPython version.
+   The macro must be placed before the symbol name.
+
+   Example::
+
+      Py_DEPRECATED(3.8) PyAPI_FUNC(int) Py_OldFunction(void);
+
+   .. versionchanged:: 3.8
+      MSVC support was added.
+
+.. c:macro:: Py_LOCAL(type)
+
+   Declare a function returning the specified *type* using a fast-calling
+   qualifier for functions that are local to the current file.
+   Semantically, this is equivalent to :samp:`static {type}`.
+
+.. c:macro:: Py_LOCAL_INLINE(type)
+
+   Equivalent to :c:macro:`Py_LOCAL` but additionally requests the function
+   be inlined.
+
+.. c:macro:: Py_LOCAL_SYMBOL
+
+   Macro used to declare a symbol as local to the shared library (hidden).
+   On supported platforms, it ensures the symbol is not exported.
+
+   On compatible versions of GCC/Clang, it
+   expands to ``__attribute__((visibility("hidden")))``.
 
 .. c:macro:: Py_EXPORTED_SYMBOL
 
@@ -461,6 +482,38 @@ complete listing.
    This macro is intended for defining CPython's C API itself;
    extension modules should not use it for their own symbols.
 
+
+Outdated macros
+---------------
+
+The following macros have been used to features that have been standardized
+in C11.
+
+.. c:macro:: Py_ALIGNED(num)
+
+   Specify alignment to *num* bytes on compilers that support it.
+
+   Consider using the C11 standard ``_Alignas`` specifier over this macro.
+
+.. c:macro:: Py_LL(number)
+             Py_ULL(number)
+
+   Use *number* as a ``long long`` or ``unsigned long long`` integer literal,
+   respectively.
+
+   Expands to *number* followed by ``LL`` or ``LLU``, respectively, but will
+   expand to some compiler-specific suffixes on some older compilers.
+
+   Consider using the C99 standard suffixes ``LL`` and ``LLU`` directly.
+
+.. c:macro:: Py_MEMCPY(dest, src, n)
+
+   This is a :term:`soft deprecated` alias to :c:func:`!memcpy`.
+   Use :c:func:`!memcpy` directly instead.
+
+   .. deprecated:: 3.14
+      The macro is :term:`soft deprecated`.
+
 .. c:macro:: Py_VA_COPY
 
    This is a :term:`soft deprecated` alias to the C99-standard ``va_copy``

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to