summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Epler <jepler@unpythonic.net>2025-09-26 09:43:58 -0500
committerDamien George <damien@micropython.org>2025-10-04 15:47:51 +1000
commit099991f3ef4a21f5bdd00767e68e7cad9ce925e4 (patch)
treee07f4a98aecb17eb12620be000971c1b47b0fdd3
parent3ec8b9a77c598104d5caf02e0b6e45d9f5d139dd (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.h9
1 files changed, 8 insertions, 1 deletions
diff --git a/py/misc.h b/py/misc.h
index ee33f84e8..ab40d3d98 100644
--- a/py/misc.h
+++ b/py/misc.h
@@ -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