diff options
author | Jeff Epler <jepler@unpythonic.net> | 2025-09-26 09:43:58 -0500 |
---|---|---|
committer | Damien George <damien@micropython.org> | 2025-10-04 15:47:51 +1000 |
commit | 099991f3ef4a21f5bdd00767e68e7cad9ce925e4 (patch) | |
tree | e07f4a98aecb17eb12620be000971c1b47b0fdd3 | |
parent | 3ec8b9a77c598104d5caf02e0b6e45d9f5d139dd (diff) |
py/misc: Use _Static_assert for MP_STATIC_ASSERT where possible.
Or use C++ `static_assert` when that's available.
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.
See related issue #18116.
Signed-off-by: Jeff Epler <jepler@unpythonic.net>
-rw-r--r-- | py/misc.h | 9 |
1 files changed, 8 insertions, 1 deletions
@@ -67,7 +67,14 @@ typedef unsigned int uint; #define MP_STRINGIFY(x) MP_STRINGIFY_HELPER(x) // Static assertion macro +#if __cplusplus +#define MP_STATIC_ASSERT(cond) static_assert((cond), #cond) +#elif __GNUC__ >= 5 || __STDC_VERSION__ >= 201112L +#define MP_STATIC_ASSERT(cond) _Static_assert((cond), #cond) +#else #define MP_STATIC_ASSERT(cond) ((void)sizeof(char[1 - 2 * !(cond)])) +#endif + // In C++ things like comparing extern const pointers are not constant-expressions so cannot be used // in MP_STATIC_ASSERT. Note that not all possible compiler versions will reject this. Some gcc versions // do, others only with -Werror=vla, msvc always does. @@ -76,7 +83,7 @@ typedef unsigned int uint; #if defined(_MSC_VER) || defined(__cplusplus) #define MP_STATIC_ASSERT_NONCONSTEXPR(cond) ((void)1) #else -#define MP_STATIC_ASSERT_NONCONSTEXPR(cond) MP_STATIC_ASSERT(cond) +#define MP_STATIC_ASSERT_NONCONSTEXPR(cond) ((void)sizeof(char[1 - 2 * !(cond)])) #endif // Round-up integer division |