classification
Title: Stable ABI should avoid `enum`
Type: Stage:
Components: C API Versions:
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: petr.viktorin
Priority: normal Keywords:

Created on 2021-07-23 15:23 by petr.viktorin, last changed 2021-07-23 15:49 by petr.viktorin.

Messages (3)
msg398067 - (view) Author: Petr Viktorin (petr.viktorin) * (Python committer) Date: 2021-07-23 15:23
Adding a new enumerator to a C enum can change the size of the type,
which would break the ABI.
This is not often a problem in practice, but the rules around when it is a problem and when it isn't are complicated enough that I believe enum should not be used in the stable ABI (possibly with well-reasoned exceptions)

AFAICS, the rules are:
- In C++, an incompatible change to an enum is one that changes the size of the *smallest bit field large enough to hold all enumerators*. Values outside the range cause undefined/unspecified behavior.
- In C, it looks like enums that fit in `char` are safe.

(Also, the compiler-defined size of enums will make it more cumbersome to formally define an ABI for non-C languages.)
msg398070 - (view) Author: Petr Viktorin (petr.viktorin) * (Python committer) Date: 2021-07-23 15:28
Devguide PR: https://github.com/python/devguide/pull/730
msg398071 - (view) Author: Petr Viktorin (petr.viktorin) * (Python committer) Date: 2021-07-23 15:49
As far as I can see, the current enums in the stable ABI are:

PySendResult from object.h, return value of PyObject_Send:
    typedef enum {
        PYGEN_RETURN = 0,
        PYGEN_ERROR = -1,
        PYGEN_NEXT = 1,
    } PySendResult;
(This is unlikely to change in the future, but added in 3.10, maybe it can be converted to int.)

PyLockStatus from pythread.h, return value of PyThread_acquire_lock_timed:
    typedef enum PyLockStatus {
        PY_LOCK_FAILURE = 0,
        PY_LOCK_ACQUIRED = 1,
        PY_LOCK_INTR
    } PyLockStatus;
(This has been there for a long time so shouldn't be changed now.)

PyGILState_STATE from pystate.h, for PyGILState_Ensure/PyGILState_Release:
    typedef
        enum {PyGILState_LOCKED, PyGILState_UNLOCKED}
        PyGILState_STATE;
(Also is unlikely to change in the future.)
History
Date User Action Args
2021-07-23 15:49:43petr.viktorinsetnosy: - corona10
messages: + msg398071
2021-07-23 15:44:16corona10setnosy: + corona10
2021-07-23 15:28:58petr.viktorinsetmessages: + msg398070
2021-07-23 15:23:37petr.viktorincreate