-
-
Notifications
You must be signed in to change notification settings - Fork 8.6k
MP_STATIC_ASSERT: Use _Static_assert or c++ static_assert #18145
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
Conversation
Signed-off-by: Angus Gratton <[email protected]>
.. or c++ static_assert where possible. For the same reasons that C++ has trouble with "nonconstexpr" static assertions, _Static_assert rejects such expression as well. So, fall back to the old sizeof-array based implementation in that case. When _Static_assert can be used, the diagnostic quality is improved: ``` ../py/objint.c: In function ‘mp_obj_int_make_new’: ../py/misc.h:67:32: error: static assertion failed: "37 == 42" ../py/objint.c:45:5: note: in expansion of macro ‘MP_STATIC_ASSERT’ ``` As compared to a diagnostic about ``` ../py/misc.h:71:50: error: size of unnamed array is negative ``` Testing on godbolt indicated that this actually works back to gcc 4.5, but it's easier to use GNUC >= 5 as the test; Hypothetical users of 4.5, 4.6, or 4.7 will just get slightly worse diagnostics. Related: micropython#18116 Signed-off-by: Jeff Epler <[email protected]>
|
Code size report: |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #18145 +/- ##
=======================================
Coverage 98.38% 98.38%
=======================================
Files 171 171
Lines 22287 22287
=======================================
Hits 21928 21928
Misses 359 359 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
This warning was enabled by default on clang 17.0.0 on macOS 26. Disable it, because we want to make these checks at compile-time even if it requires an extension. Signed-off-by: Jeff Epler <[email protected]>
|
Based on some testing in godbolt, the pragma to disable the warning flag is accepted without complaint (under -Werror) even in extremely old clang versions. |
|
[the commit message check is failing because there's the merge commit for #18129 testing] |
|
This fixes #18116 for me. |
projectgus
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @jepler, I started down the same path as you but got stuck on what to do about the MP_STATIC_ASSERT_NONCONSTEXPR case. I think this is the right way forward.
I wonder if we should leave macos-26 in place, presumably at some point this will become macos-latest anyway?
|
There's also a few other tests that should probably be added --- for the I did something very similar to this for #18148, with the C23 |
| #define MP_STRINGIFY(x) MP_STRINGIFY_HELPER(x) | ||
|
|
||
| // Static assertion macro | ||
| #if __cplusplus |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| #if __cplusplus | |
| #if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 202311L)) || (defined(__cplusplus) && (__cplusplus >= 201103L)) || __has_feature(cxx_static_assert) || defined(static_assert) | |
| // C23 keyword: https://en.cppreference.com/w/c/language/static_assert.html | |
| // C++11 declaration: https://en.cppreference.com/w/cpp/language/static_assert.html | |
| // Clang feature: https://clang.llvm.org/docs/LanguageExtensions.html#c-11-static-assert | |
| // assert.h macro: https://en.cppreference.com/w/c/error/static_assert.html |
| // Static assertion macro | ||
| #if __cplusplus | ||
| #define MP_STATIC_ASSERT(cond) static_assert((cond), #cond) | ||
| #elif __GNUC__ >= 5 || __STDC_VERSION__ >= 201112L |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| #elif __GNUC__ >= 5 || __STDC_VERSION__ >= 201112L | |
| #elif (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || (defined(__GNUC__) && __GNUC__ >= 5) || __has_feature(c_static_assert) | |
| // C11 keyword: https://en.cppreference.com/w/c/language/static_assert.html | |
| // GCC feature: https://www.gnu.org/software/c-intro-and-ref/manual/html_node/Static-Assertions.html | |
| // Clang feature: https://clang.llvm.org/docs/LanguageExtensions.html#c11-static-assert |
|
I'll also note that MSVC has the macro |
|
@AJMansfield I gently disagree with your proposed change to the enabling condition, but I also feel like we've discussed it before and I don't mean to rehash old settled topics. If this rings a bell do you recall specifics or have a link to the old discussion? I only found #17735 (review) in my search. gcc (actually cpp) documentation says that " As an extension, gcc has long offered support for Similar to how we ended up using version checks for MP_GCC_HAS_BUILTIN_OVERFLOW (but supplemented it with some I'm also not sure if To check my theories I tried this on godbolt across a range of gcc versions with -std=c99: gcc 4.7, 5.1, ..., 12.5, 13.4 build with no diagnostics. So, I actually didn't find any compiler versions where the The other positive thing I see your version doing is fixing how things work under |
I don't believe it's a conversation I've had --- glad for the reference on how MicroPython usually conducts things though.
Indeed, my proposal was a bit premature, I should've spent a bit more time reading and testing things first 🙃. The only (possible) benefit there might be to do with clang support. Also useful note on the
Agreed --- and it's not that I'd expect anyone with a stupid-mode compiler that actually breaks on undefined macros, but if there's anywhere to do belt-and-braces on that it's the macros designed to bridge compatibility gaps between different compiler versions. |
dpgeorge
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think what's in this PR at the moment is fine: it works, is an improvement on the diagnostics for failing static assertions, and fixes issue #18116.
Further improvements can be made later if needed.
Yes, there was a discussion about this somewhere. I'd be happy if we were able to turn that warning on (although I guess it might require quite a few changes...). |
|
We also had to do this in CircuitPython: adafruit#10656. But |
Summary
When _Static_assert can be used, the diagnostic quality is improved:
As compared to a diagnostic about
Related: #18116
Testing
I built the unix coverage build locally. Since this is a compile-time only test, CI will be a good test.
Trade-offs and Alternatives
Testing on godbolt indicated that this actually works back to gcc 4.5, but it's easier to use GNUC >= 5 as the test; Hypothetical users of 4.5, 4.6, or 4.7 will just get slightly worse diagnostics.
For "nonconstant" static asserts, the array trick still needs to be used; _Static_assert rejects these expressions just like C++ static_assert does.