1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
/*
* SPDX-FileCopyrightText: 2019-2023, Alejandro Colomar <alx@kernel.org>
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef SHADOW_INCLUDE_LIBMISC_MUST_BE_H_
#define SHADOW_INCLUDE_LIBMISC_MUST_BE_H_
#include <config.h>
#include <assert.h>
/*
* SYNOPSIS
* int must_be(bool e);
*
* ARGUMENTS
* e Expression to be asserted.
*
* DESCRIPTION
* This macro fails compilation if 'e' is false. If 'e' is true,
* it returns (int) 0, so it doesn't affect the expression in which
* it is contained.
*
* This macro is similar to static_assert(3). While
* static_assert(3) can only be used where a statement is allowed,
* this must_be() macro can be used wherever an expression is
* allowed.
*
* RETURN VALUE
* 0
*
* ERRORS
* If 'e' is false, the compilation will fail, as when using
* static_assert(3).
*
* EXAMPLES
* #define must_be_array(a) must_be(is_array(a))
*
* #define NITEMS(a) (sizeof(a) / sizeof(*(a)) + must_be_array(a))
*
* int foo[42];
* int bar[NITEMS(foo)];
*/
#define must_be(e) \
( \
0 * (int) sizeof( \
struct { \
static_assert(e, ""); \
int ISO_C_forbids_a_struct_with_no_members_; \
} \
) \
)
/*
* SYNOPSIS
* int must_be_array(a);
*
* ARGUMENTS
* a Array.
*
* DESCRIPTION
* This macro fails compilation if 'a' is not an array. It is
* useful in macros that accept an array as a parameter, where this
* macro can validate the macro argument. It prevent passing a
* pointer to such macros, which would otherwise produce silent
* bugs.
*
* RETURN VALUE
* 0
*
* ERRORS
* If 'a' is not an array, the compilation will fail.
*
* EXAMPLES
* int a[10];
* int *p;
*
* must_be_array(a); // Ok
* must_be_array(p); // Compile-time error
*
* SEE ALSO
* must_be()
*/
#define is_same_type(a, b) __builtin_types_compatible_p(a, b)
#define is_same_typeof(a, b) is_same_type(typeof(a), typeof(b))
#define is_array(a) (!is_same_typeof((a), &(a)[0]))
#define must_be_array(a) must_be(is_array(a))
#endif // include guard
|