STINNER Victor <vstin...@redhat.com> added the comment:
Advantages of inline functions over C macros: https://mail.python.org/pipermail/python-dev/2018-November/155805.html There are multiple advantages: * Better development and debugging experience: tools understand inlined functions much better than C macros: gdb, Linux perf, etc. * Better API: arguments now have a type and the function has a return type. In practice, some macros still cast their argument to PyObject* to not introduce new compiler warnings in Python 3.8. For example, even if Py_INCREF() is documented (*) as a function expecting PyObject*, it accepts any pointer type (PyTupleObject*, PyUnicodeObject*, etc.). Technically, it also accepts PyObject** which is a bug, but that's a different story ;-) * Much better code, just plain regular C. C macros are ugly: "do { ... } while (0)" workaround, additional parenthesis around each argument, strange "expr1, expr2" syntax of "macro expression" which returns a value (inline function just uses regular "return" and ";" at the end of instructions), strange indentation, etc. * No more "macro pitfals": https://gcc.gnu.org/onlinedocs/cpp/Macro-Pitfalls.html * Local variables no longer need a magic name to avoid risk of name conflict, and have a clearly defined scope. Py_DECREF() and _Py_XINCREF() no longer need a local variable since it's argument already has a clearly defined type: PyObject*. I introduced a new variable in _Py_Dealloc() to fix a possible race condition. Previously, the variable was probably avoided because it's tricky use variables in macros. * #ifdef can now be used inside the inline function: it makes the code easier to understand. * etc. Are you aware that Python had macros like: #define _Py_REF_DEBUG_COMMA , #define _Py_CHECK_REFCNT(OP) /* a semicolon */; I let you judge the quality of this macro: #define _Py_NewReference(op) ( \ _Py_INC_TPALLOCS(op) _Py_COUNT_ALLOCS_COMMA \ _Py_INC_REFTOTAL _Py_REF_DEBUG_COMMA \ Py_REFCNT(op) = 1) Is it an expression? Can it be used in "if (test) _Py_NewReference(op);"? It doesn't use the "do { ... } while (0)" protection against macro pitfals. (*) Py_INCREF doc: https://docs.python.org/dev/c-api/refcounting.html#c.Py_INCREF ---------- _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue35059> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com