Hi, I'm working on cleaning up the C API, long rationale: https://pythoncapi.readthedocs.io/
Macros are causing multiple issues: * They often leak "implementation details" and so are incompatible with a stable ABI * They have multiple pitfalls: https://gcc.gnu.org/onlinedocs/cpp/Macro-Pitfalls.html * They require hacks like "do { ... } while (0)" to behave properly as a statement, otherwise they can introduce bugs * They don't "check" argument types and their return type is often unclear, or worse depends on the arguments type * Variable scoping can be an issue. For example, Py_SETREF() macro in Python 3.8 uses a "_py_tmp" variable name, rather than being able to use a more common name like "op" or "obj". * etc. Static inline functions behave as regular functions: a function call is an expression, parameter types and return type are well defined, scoping is well defined by the C language, etc. For backward compatibility, I kept implicit cast to PyObject* using a macro. Example: static inline void _Py_INCREF(PyObject *op) { _Py_INC_REFTOTAL; op->ob_refcnt++; } #define Py_INCREF(op) _Py_INCREF(_PyObject_CAST(op)) Static inline functions like _Py_INCREF() are still incompatible with a stable ABI, but it's a tradeoff between correctness and practicability. I wrote an article about my work on the C API in Python 3.8: https://vstinner.github.io/split-include-directory-python38.html -- Macros are still used for some corner cases. For example, the following macro opens a block with { : #define Py_BEGIN_ALLOW_THREADS { \ PyThreadState *_save; \ _save = PyEval_SaveThread(); and this one closes the block: #define Py_END_ALLOW_THREADS PyEval_RestoreThread(_save); \ } Note also the "_save" variable which has a local scope ;-) Another example of special macro, the following macro uses "return" which cannot be used like that using a function: #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None By the way, I would prefer "return Py_GetNone()", but that's a different discussion ;-) -- Macros are sometimes overriden by #define, or even #undef followed by #define. In my own projects, I prefer "const int my_constant = 123;" rather than "#define constant 123". In Python, I'm using the status quo: "#define constant 123". Victor Le mer. 4 déc. 2019 à 13:19, Skip Montanaro <skip.montan...@gmail.com> a écrit : > > As I wander around the code base, I keep seeing macro definitions in > the C code. For example, there are four CALL* macros defined in > Python/ast_opt.c which contain not entirely trivial bits of syntax. > That code is from 2017 (as compared to, say, Modules/audioop.c, which > first saw the light of day in 1992) I see the inline keyword used > unconditionally in many places. > > I don't think stable code which uses macros should be changed (though > I see the INCREF/DECREF macros just call private inline functions, so > some conversion has clearly been done). Still, in new code, shouldn't > the use of macros for more than trivial use cases (constant defs, > simple one-liners) be discouraged at this point? > > Skip > _______________________________________________ > Python-Dev mailing list -- python-dev@python.org > To unsubscribe send an email to python-dev-le...@python.org > https://mail.python.org/mailman3/lists/python-dev.python.org/ > Message archived at > https://mail.python.org/archives/list/python-dev@python.org/message/AVF6W3PMCAQK73NXOXHMHNW2KP7FJOIJ/ > Code of Conduct: http://python.org/psf/codeofconduct/ -- Night gathers, and now my watch begins. It shall not end until my death. _______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/LGORMVPTX42UIPNTG72K5BMGQTACNQ6X/ Code of Conduct: http://python.org/psf/codeofconduct/