Skip to content

Commit c1fda68

Browse files
author
Erlend Egeberg Aasland
authored
PEP 670 amendments (#2157)
1 parent 2263e93 commit c1fda68

File tree

1 file changed

+61
-27
lines changed

1 file changed

+61
-27
lines changed

pep-0670.rst

Lines changed: 61 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,13 @@ The `GCC documentation
6060
<https://gcc.gnu.org/onlinedocs/cpp/Macro-Pitfalls.html>`_ lists several
6161
common macro pitfalls:
6262

63-
- Misnesting;
64-
- Operator precedence problems;
65-
- Swallowing the semicolon;
66-
- Duplication of side effects;
67-
- Self-referential macros;
68-
- Argument prescan;
69-
- Newlines in arguments.
63+
- Misnesting
64+
- Operator precedence problems
65+
- Swallowing the semicolon
66+
- Duplication of side effects
67+
- Self-referential macros
68+
- Argument prescan
69+
- Newlines in arguments
7070

7171

7272
Performance and inlining
@@ -91,7 +91,7 @@ performances and reliable benchmarks. PGO helps the compiler to decide
9191
if function should be inlined or not.
9292

9393
``./configure --with-pydebug`` uses the ``-Og`` compiler option if it's
94-
supported by the compiler (GCC and LLVM clang support it): optimize
94+
supported by the compiler (GCC and LLVM Clang support it): optimize
9595
debugging experience. Otherwise, the ``-O0`` compiler option is used:
9696
disable most optimizations.
9797

@@ -119,11 +119,10 @@ The ``Py_ALWAYS_INLINE`` macro can be used to force inlining. This macro
119119
uses ``__attribute__((always_inline))`` with GCC and Clang, and
120120
``__forceinline`` with MSC.
121121

122-
So far, previous attempts to use ``Py_ALWAYS_INLINE`` didn't show any
123-
benefit and were abandoned. See for example: `bpo-45094
124-
<https://bugs.python.org/issue45094>`_: "Consider using
125-
``__forceinline`` and ``__attribute__((always_inline))`` on static
126-
inline functions (``Py_INCREF``, ``Py_TYPE``) for debug build".
122+
Previous attempts to use ``Py_ALWAYS_INLINE`` didn't show any benefit, and were
123+
abandoned. See for example: `bpo-45094 <https://bugs.python.org/issue45094>`_:
124+
"Consider using ``__forceinline`` and ``__attribute__((always_inline))`` on
125+
static inline functions (``Py_INCREF``, ``Py_TYPE``) for debug build".
127126

128127
When the ``Py_INCREF()`` macro was converted to a static inline
129128
functions in 2018 (`commit
@@ -140,8 +139,8 @@ Disable inlining
140139
----------------
141140

142141
On the other side, the ``Py_NO_INLINE`` macro can be used to disable
143-
inlining. It is useful to reduce the stack memory usage. It is
144-
especially useful on a LTO+PGO build which is more aggressive to inline
142+
inlining. It can be used to reduce the stack memory usage, or to prevent
143+
inlining on LTO+PGO builds, which are generally more aggressive to inline
145144
code: see `bpo-33720 <https://bugs.python.org/issue33720>`_. The
146145
``Py_NO_INLINE`` macro uses ``__attribute__ ((noinline))`` with GCC and
147146
Clang, and ``__declspec(noinline)`` with MSC.
@@ -164,6 +163,7 @@ The following macros should not be converted:
164163
* Compatibility layer for different C compilers, C language extensions,
165164
or recent C features.
166165
Example: ``#define Py_ALWAYS_INLINE __attribute__((always_inline))``.
166+
* Macros that need the stringification or concatenation feature of the C preprocessor.
167167

168168

169169
Convert static inline functions to regular functions
@@ -189,7 +189,7 @@ Cast to PyObject*
189189
When a macro is converted to a function and the macro casts its
190190
arguments to ``PyObject*``, the new function comes with a new macro
191191
which cast arguments to ``PyObject*`` to prevent emitting new compiler
192-
warnings. So the converted functions still accept pointers to other
192+
warnings. This implies that a converted function will accept pointers to
193193
structures inheriting from ``PyObject`` (ex: ``PyTupleObject``).
194194

195195
For example, the ``Py_TYPE(obj)`` macro casts its ``obj`` argument to
@@ -212,14 +212,10 @@ Remove the return value
212212
-----------------------
213213

214214
When a macro is implemented as an expression, it has an implicit return
215-
value. In some cases, the macro must not have a return value and can be
216-
misused in third party C extensions. See `bpo-30459
217-
<https://bugs.python.org/issue30459>`_ for the example of
218-
``PyList_SET_ITEM()`` and ``PyCell_SET()`` macros. It is not easy to
219-
notice this issue while reviewing macro code.
220-
221-
These macros are converted to functions using the ``void`` return type
222-
to remove their return value. Removing the return value aids detecting
215+
value. This macro pitfall can be misused in third party C extensions. See
216+
`bpo-30459 <https://bugs.python.org/issue30459>`_ regarding the misuse of the
217+
``PyList_SET_ITEM()`` and ``PyCell_SET()`` macros. Such pitfalls are hard to
218+
catch while reviewing macro code. Removing the return value aids detecting
223219
bugs in C extensions when the C API is misused.
224220

225221

@@ -249,9 +245,9 @@ the macro.
249245
People using macros should be considered "consenting adults". People who
250246
feel unsafe with macros should simply not use them.
251247

252-
The idea was rejected because macros are error prone and it is too easy
253-
to miss a macro pitfall when writing a macro. Moreover, macros are
254-
harder to read and to maintain than functions.
248+
These ideas are rejected because macros _are_ error prone, and it is too easy
249+
to miss a macro pitfall when writing and reviewing macro code. Moreover, macros
250+
are harder to read and maintain than functions.
255251

256252

257253
Examples of hard to read macros
@@ -318,6 +314,44 @@ Python 3.8 function (simplified code)::
318314
}
319315

320316

317+
PyUnicode_READ_CHAR()
318+
---------------------
319+
320+
This macro reuses arguments, and possibly calls ``PyUnicode_KIND`` multiple
321+
times::
322+
323+
#define PyUnicode_READ_CHAR(unicode, index) \
324+
(assert(PyUnicode_Check(unicode)), \
325+
assert(PyUnicode_IS_READY(unicode)), \
326+
(Py_UCS4) \
327+
(PyUnicode_KIND((unicode)) == PyUnicode_1BYTE_KIND ? \
328+
((const Py_UCS1 *)(PyUnicode_DATA((unicode))))[(index)] : \
329+
(PyUnicode_KIND((unicode)) == PyUnicode_2BYTE_KIND ? \
330+
((const Py_UCS2 *)(PyUnicode_DATA((unicode))))[(index)] : \
331+
((const Py_UCS4 *)(PyUnicode_DATA((unicode))))[(index)] \
332+
) \
333+
))
334+
335+
Possible implementation as a static inlined function::
336+
337+
static inline Py_UCS4
338+
PyUnicode_READ_CHAR(PyObject *unicode, Py_ssize_t index)
339+
{
340+
assert(PyUnicode_Check(unicode));
341+
assert(PyUnicode_IS_READY(unicode));
342+
343+
switch (PyUnicode_KIND(unicode)) {
344+
case PyUnicode_1BYTE_KIND:
345+
return (Py_UCS4)((const Py_UCS1 *)(PyUnicode_DATA(unicode)))[index];
346+
case PyUnicode_2BYTE_KIND:
347+
return (Py_UCS4)((const Py_UCS2 *)(PyUnicode_DATA(unicode)))[index];
348+
case PyUnicode_4BYTE_KIND:
349+
default:
350+
return (Py_UCS4)((const Py_UCS4 *)(PyUnicode_DATA(unicode)))[index];
351+
}
352+
}
353+
354+
321355
Macros converted to functions since Python 3.8
322356
==============================================
323357

0 commit comments

Comments
 (0)