From: Michał Janiszewski janisozaur@gmail.com
Inspired by kernel check and recent unification of ARRAY_SIZE, provide a way of enforcing the macro can only be applied to actual arrays and not to pointers.
v2: Fix parentheses
Signed-off-by: Michał Janiszewski janisozaur@gmail.com --- include/winnt.h | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/include/winnt.h b/include/winnt.h index 7f822c4aec..b99a375ab0 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -760,7 +760,26 @@ typedef struct _MEMORY_BASIC_INFORMATION ((type *)((PCHAR)(address) - offsetof(type, field)))
#ifdef __WINESRC__ -# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +// Validate types used in the expression. +// Based on https://elixir.bootlin.com/linux/v4.17.4/source/include/linux/kernel.h#L71 + +#ifdef __GNUC__ +/** + * Force a compilation error if condition is true, but also produce a + * result (of value 0 and type size_t), so the expression can be used + * e.g. in a structure initializer (or where-ever else comma expressions + * aren't permitted). + */ +#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); })) + +/* &a[0] degrades to a pointer: a different type from an array */ +#define __must_be_array(a) \ + BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(typeof(a), typeof(&a[0]))) +#else +#define __must_be_array(a) 0 +#endif + +# define ARRAY_SIZE(x) ((sizeof(x) / sizeof((x)[0])) + __must_be_array(x)) #endif
/* Types */
Resend
On Sun, 8 Jul 2018 at 23:34, janisozaur@gmail.com wrote:
From: Michał Janiszewski janisozaur@gmail.com
Inspired by kernel check and recent unification of ARRAY_SIZE, provide a way of enforcing the macro can only be applied to actual arrays and not to pointers.
v2: Fix parentheses
Signed-off-by: Michał Janiszewski janisozaur@gmail.com
include/winnt.h | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/include/winnt.h b/include/winnt.h index 7f822c4aec..b99a375ab0 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -760,7 +760,26 @@ typedef struct _MEMORY_BASIC_INFORMATION ((type *)((PCHAR)(address) - offsetof(type, field)))
#ifdef __WINESRC__ -# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +// Validate types used in the expression. +// Based on https://elixir.bootlin.com/linux/v4.17.4/source/include/linux/kernel.h#L71
+#ifdef __GNUC__ +/**
- Force a compilation error if condition is true, but also produce a
- result (of value 0 and type size_t), so the expression can be used
- e.g. in a structure initializer (or where-ever else comma expressions
- aren't permitted).
- */
+#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
+/* &a[0] degrades to a pointer: a different type from an array */ +#define __must_be_array(a) \
- BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(typeof(a), typeof(&a[0])))
+#else +#define __must_be_array(a) 0 +#endif
+# define ARRAY_SIZE(x) ((sizeof(x) / sizeof((x)[0])) + __must_be_array(x)) #endif
/* Types */
2.18.0