std-aux: rework NM_STATIC_ASSERT_EXPR() macro

Replace NM_STATIC_ASSERT_EXPR() by NM_STATIC_ASSERT_EXPR_1() and
NM_STATIC_ASSERT_EXPR_VOID(). NM_STATIC_ASSERT_EXPR_VOID() can be
used as an expression that returns void (that is, a simple statement).
On the other hand, NM_STATIC_ASSERT_EXPR_1() itself retuns
a compile time constant of int value 1. The latter is useful, because
we can use the 1 to combine static assertions in expressions that
are themself compile time constants, like

  #define STATIC_CHECK_AND_GET(cond, value) \
      (NM_STATIC_ASSERT_EXPR_1(cond) ? (value) : (value))

This is itself a compile time constant if value is a compile
time constant. Also, it does the compile time check that "cond"
is true.
This commit is contained in:
Thomas Haller 2021-06-22 22:43:12 +02:00
parent 74996782eb
commit 1e29a7e66b
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
2 changed files with 30 additions and 5 deletions

View file

@ -30,6 +30,31 @@ G_STATIC_ASSERT(4 == _nm_alignof(NMIPAddr));
/*****************************************************************************/
static void
test_nm_static_assert(void)
{
int v1[NM_STATIC_ASSERT_EXPR_1(1)];
typeof(NM_STATIC_ASSERT_EXPR_1(1)) v_int;
int * p_int;
G_STATIC_ASSERT(sizeof(v1) == sizeof(int));
G_STATIC_ASSERT(NM_STATIC_ASSERT_EXPR_1(1) == 1);
G_STATIC_ASSERT(NM_STATIC_ASSERT_EXPR_1(NM_STATIC_ASSERT_EXPR_1(1)) == 1);
G_STATIC_ASSERT(NM_STATIC_ASSERT_EXPR_1(NM_STATIC_ASSERT_EXPR_1(NM_STATIC_ASSERT_EXPR_1(1)))
== 1);
g_assert(NM_STATIC_ASSERT_EXPR_1(2) == 1);
p_int = &v_int;
g_assert(&v_int == p_int);
(void) NM_STATIC_ASSERT_EXPR_1(2 > 1);
NM_STATIC_ASSERT_EXPR_VOID(2 > 1);
}
/*****************************************************************************/
static void
test_gpid(void)
{
@ -1352,6 +1377,7 @@ main(int argc, char **argv)
{
nmtst_init(&argc, &argv, TRUE);
g_test_add_func("/general/test_nm_static_assert", test_nm_static_assert);
g_test_add_func("/general/test_gpid", test_gpid);
g_test_add_func("/general/test_monotonic_timestamp", test_monotonic_timestamp);
g_test_add_func("/general/test_nmhash", test_nmhash);

View file

@ -182,11 +182,10 @@ typedef uint64_t _nm_bitwise nm_be64_t;
})
#define NM_STATIC_ASSERT(cond) static_assert(cond, "")
#define NM_STATIC_ASSERT_EXPR(cond) \
({ \
NM_STATIC_ASSERT(cond); \
1; \
})
#define NM_STATIC_ASSERT_EXPR_1(cond) \
(sizeof(struct { char __static_assert_expr_1[(cond) ? 1 : -1]; }) == 1)
#define NM_STATIC_ASSERT_EXPR_VOID(cond) \
((void) (sizeof(struct { char __static_assert_expr_void[(cond) ? 1 : -1]; }) == 1))
/*****************************************************************************/