Casts are unsafe.
Compound literals also have the ability of converting values, but they
don't have the unwanted effects on safety --casts disable most useful
diagnostics--.
Compound literals are lvalues, which means their address can be taken,
and they can also be assigned to. To avoid this, we force lvalue
conversion through a statement expression.
Signed-off-by: Alejandro Colomar <alx@kernel.org>
#define CALLOC(n, T) CALLOC_(n, typeas(T))
#define CALLOC_(n, T) \
-( \
- (T *) calloc(n, sizeof(T)) \
-)
+({ \
+ (T *){calloc(n, sizeof(T))}; \
+})
#define XCALLOC(n, T) exit_if_null(CALLOC(n, T))
#define MALLOC(n, T) MALLOC_(n, typeas(T))
#define MALLOC_(n, T) \
-( \
- (T *) mallocarray(n, sizeof(T)) \
-)
+({ \
+ (T *){mallocarray(n, sizeof(T))}; \
+})
#define XMALLOC(n, T) exit_if_null(MALLOC(n, T))
#define REALLOC(p, n, T) REALLOC_(p, n, typeas(T))
#define REALLOC_(p, n, T) \
-( \
- _Generic(p, T *: (T *) reallocarray_(p, n, sizeof(T))) \
-)
+({ \
+ _Generic(p, T *: (T *){reallocarray_(p, n, sizeof(T))}); \
+})
#define reallocarray_(p, n, size) reallocarray(p, (n) ?: 1, (size) ?: 1)
#define REALLOCF(p, n, T) REALLOCF_(p, n, typeas(T))
#define REALLOCF_(p, n, T) \
-( \
- _Generic(p, T *: (T *) reallocarrayf_(p, n, sizeof(T))) \
-)
+({ \
+ _Generic(p, T *: (T *){reallocarrayf_(p, n, sizeof(T))}); \
+})
#define reallocarrayf_(p, n, size) reallocarrayf(p, (n) ?: 1, (size) ?: 1)
#define CMP(T) \
( \
- _Generic((T) 0, \
+ _Generic((T){}, \
int: cmp_int, \
long: cmp_long, \
unsigned int: cmp_uint, \
({ \
_Generic(k, T *: (void)0, const T *: (void)0); \
_Generic(a, T *: (void)0, const T *: (void)0); \
- (T *) lfind_(k, a, n, sizeof(T), cmp); \
+ (T *){lfind_(k, a, n, sizeof(T), cmp)}; \
})
#define LFIND(T, ...) lfind_T(T, __VA_ARGS__, CMP(T))
({ \
_Generic(k, T *: (void)0, const T *: (void)0); \
_Generic(a, T *: (void)0); \
- (T *) lsearch(k, a, n, sizeof(T), cmp); \
+ (T *){lsearch(k, a, n, sizeof(T), cmp)}; \
})
#define LSEARCH(T, ...) lsearch_T(T, __VA_ARGS__, CMP(T))
#define typeas(T) typeof((T){})
-#define ssizeof(x) ((ssize_t) sizeof(x))
+#define ssizeof(x) ({(ssize_t){sizeof(x)};})
#define memberof(T, member) ((T){}.member)
#define WIDTHOF(x) (sizeof(x) * CHAR_BIT)