Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use static asserts in C code #69744

Closed
serhiy-storchaka opened this issue Nov 5, 2015 · 17 comments
Closed

Use static asserts in C code #69744

serhiy-storchaka opened this issue Nov 5, 2015 · 17 comments
Labels
extension-modules C modules in the Modules dir interpreter-core (Objects, Python, Grammar, and Parser dirs) type-feature A feature request or enhancement

Comments

@serhiy-storchaka
Copy link
Member

BPO 25558
Nosy @vstinner, @skrah, @serhiy-storchaka
Files
  • use_Py_BUILD_ASSERT_EXPR.patch
  • macro.patch
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = <Date 2015-11-13.11:53:32.017>
    created_at = <Date 2015-11-05.16:46:40.575>
    labels = ['extension-modules', 'interpreter-core', 'type-feature']
    title = 'Use static asserts in C code'
    updated_at = <Date 2015-11-13.11:53:32.016>
    user = 'https://github.com/serhiy-storchaka'

    bugs.python.org fields:

    activity = <Date 2015-11-13.11:53:32.016>
    actor = 'serhiy.storchaka'
    assignee = 'none'
    closed = True
    closed_date = <Date 2015-11-13.11:53:32.017>
    closer = 'serhiy.storchaka'
    components = ['Extension Modules', 'Interpreter Core']
    creation = <Date 2015-11-05.16:46:40.575>
    creator = 'serhiy.storchaka'
    dependencies = []
    files = ['40955', '40956']
    hgrepos = []
    issue_num = 25558
    keywords = ['patch']
    message_count = 16.0
    messages = ['254117', '254120', '254123', '254124', '254125', '254126', '254128', '254129', '254130', '254175', '254176', '254177', '254201', '254269', '254270', '254465']
    nosy_count = 4.0
    nosy_names = ['vstinner', 'skrah', 'python-dev', 'serhiy.storchaka']
    pr_nums = []
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'enhancement'
    url = 'https://bugs.python.org/issue25558'
    versions = ['Python 3.6']

    @serhiy-storchaka
    Copy link
    Member Author

    Proposed patch converts some dynamic assert to static asserts (Py_BUILD_ASSERT_EXPR). This allows to check static invariants at compile time.

    @serhiy-storchaka serhiy-storchaka added extension-modules C modules in the Modules dir interpreter-core (Objects, Python, Grammar, and Parser dirs) type-feature A feature request or enhancement labels Nov 5, 2015
    @vstinner
    Copy link
    Member

    vstinner commented Nov 5, 2015

    + (void)Py_BUILD_ASSERT_EXPR(INT_MAX <= _PyTime_MAX / SEC_TO_NS);

    Hum, maybe the existing macro should be renamed to Py_BUILD_ASSERT_EXPR and a new Py_BUILD_ASSERT_EXPR macro should add the (void) to ignore the result? It would avoid to have to repeat (void) everywhere.

    What do you think?

    @serhiy-storchaka
    Copy link
    Member Author

    This is a public name and can be used in third-party code.

    @vstinner
    Copy link
    Member

    vstinner commented Nov 5, 2015

    This is a public name and can be used in third-party code.

    Do you mean that a library can really rely on the result!? It would be insane :-)

    @vstinner
    Copy link
    Member

    vstinner commented Nov 5, 2015

    Hum, maybe I wasn't clear: I propose attached macro.patch.

    @serhiy-storchaka
    Copy link
    Member Author

    A library can follow the example in the comment.

       #define foo_to_char(foo)  \
           ((char *)(foo)        \
            + Py_BUILD_ASSERT_EXPR(offsetof(struct foo, string) == 0))

    @skrah
    Copy link
    Mannequin

    skrah mannequin commented Nov 5, 2015

    Serhiy, could you please not change stuff that I maintain? I know
    you have the best intentions, but I really don't like these kinds
    of changes (just like you don't like trailing whitespace :).

    @serhiy-storchaka
    Copy link
    Member Author

    OK, I'll exclude Modules/_decimal/_decimal.c.

    @skrah
    Copy link
    Mannequin

    skrah mannequin commented Nov 5, 2015

    Thank you!

    @python-dev
    Copy link
    Mannequin

    python-dev mannequin commented Nov 6, 2015

    New changeset ad44d551c13c by Serhiy Storchaka in branch '3.5':
    Issue bpo-25558: Refactoring OrderedDict iteration.
    https://hg.python.org/cpython/rev/ad44d551c13c

    New changeset 51f3547da99c by Serhiy Storchaka in branch 'default':
    Issue bpo-25558: Refactoring OrderedDict iteration.
    https://hg.python.org/cpython/rev/51f3547da99c

    @serhiy-storchaka
    Copy link
    Member Author

    Wrong issue. The correct one is bpo-24726.

    @serhiy-storchaka
    Copy link
    Member Author

    Oh, no, the correct one is bpo-25410.

    @vstinner
    Copy link
    Member

    vstinner commented Nov 6, 2015

    use_Py_BUILD_ASSERT_EXPR.patch looks good to me. But you should revert the change on decimal, as asked by Stefan, and I suggested to move an assertion inside the related function (see my comment on Rietveld).

    """
    A library can follow the example in the comment.

       #define foo_to_char(foo)  \
           ((char *)(foo)        \
            + Py_BUILD_ASSERT_EXPR(offsetof(struct foo, string) == 0))
    """

    Hum ok, I know understand the "_EXPR" suffix of the macro name. Maybe it's worth to add a new #define Py_BUILD_ASSERT(expr) (void)Py_BUILD_ASSERT_EXPR(expr)" macro?

    By the way, I don't know what happens if you pass a variable to Py_BUILD_ASSERT_EXPR() rather than a constant. Maybe we could use __builtin_constant_p() on GCC? Maybe it's overcomplexicated :-)

    @python-dev
    Copy link
    Mannequin

    python-dev mannequin commented Nov 7, 2015

    New changeset 45a404d33c2d by Serhiy Storchaka in branch 'default':
    Issue bpo-25558: Use compile-time asserts.
    https://hg.python.org/cpython/rev/45a404d33c2d

    @serhiy-storchaka
    Copy link
    Member Author

    By the way, I don't know what happens if you pass a variable to Py_BUILD_ASSERT_EXPR() rather than a constant.

    If the compiler can't calculate it at compile time (e.g. int_var <= INT_MAX), your are out of luck.

    Maybe we could use __builtin_constant_p() on GCC?

    Don't know if it will help.

    @vstinner
    Copy link
    Member

    This issue can now be closed, no?

    (I don't think that it's worth to add a new macro and make the existing macro more strict.)

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    @namniav
    Copy link

    namniav commented Apr 22, 2024

    By the way, I don't know what happens if you pass a variable to Py_BUILD_ASSERT_EXPR() rather than a constant.

    If the compiler can't calculate it at compile time (e.g. int_var <= INT_MAX), your are out of luck.

    If the compiler supports variable-length arrays(VLA) then it is unspecified whether or not the size expression is evaluated and no assertion can be checked at compile time.
    See #118124 and https://en.cppreference.com/w/c/language/sizeof

    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    extension-modules C modules in the Modules dir interpreter-core (Objects, Python, Grammar, and Parser dirs) type-feature A feature request or enhancement
    Projects
    None yet
    Development

    No branches or pull requests

    3 participants