4 #include <ccan/build_assert/build_assert.h>
7 * cast_signed - cast a (const) char * to/from (const) signed/unsigned char *.
8 * @type: some char * variant.
9 * @expr: expression (of some char * variant) to cast.
11 * Some libraries insist on an unsigned char in various places; cast_signed
12 * makes sure (with suitable compiler) that the expression you are casting
13 * only differs in signed/unsigned, not in type or const-ness.
15 #define cast_signed(type, expr) \
17 + BUILD_ASSERT_OR_ZERO(cast_sign_compatible(type, (expr))))
20 * cast_const - remove a const qualifier from a pointer.
21 * @type: some pointer type.
22 * @expr: expression to cast.
24 * This ensures that you are only removing the const qualifier from an
25 * expression. The expression must otherwise match @type.
27 * If @type is a pointer to a pointer, you must use cast_const2 (etc).
30 * // Dumb open-coded strstr variant.
31 * static char *find_needle(const char *haystack)
34 * for (i = 0; i < strlen(haystack); i++)
35 * if (memcmp("needle", haystack+i, strlen("needle")) == 0)
36 * return cast_const(char *, haystack+i);
40 #define cast_const(type, expr) \
42 + BUILD_ASSERT_OR_ZERO(cast_const_compat1((expr), type)))
45 * cast_const2 - remove a const qualifier from a pointer to a pointer.
46 * @type: some pointer to pointer type.
47 * @expr: expression to cast.
49 * This ensures that you are only removing the const qualifier from an
50 * expression. The expression must otherwise match @type.
52 #define cast_const2(type, expr) \
54 + BUILD_ASSERT_OR_ZERO(cast_const_compat2((expr), type)))
57 * cast_const3 - remove a const from a pointer to a pointer to a pointer..
58 * @type: some pointer to pointer to pointer type.
59 * @expr: expression to cast.
61 * This ensures that you are only removing the const qualifier from an
62 * expression. The expression must otherwise match @type.
64 #define cast_const3(type, expr) \
66 + BUILD_ASSERT_OR_ZERO(cast_const_compat3((expr), type)))
70 * cast_static - explicit mimic of implicit cast.
72 * @expr: expression to cast.
74 * This ensures that the cast is not to or from a pointer: it can only be
75 * an implicit cast, such as a pointer to a similar const pointer, or between
78 #if HAVE_COMPOUND_LITERALS
79 #define cast_static(type, expr) \
80 ((struct { type x; }){(expr)}.x)
82 #define cast_static(type, expr) \
86 /* Herein lies the gcc magic to evoke compile errors. */
87 #if HAVE_BUILTIN_CHOOSE_EXPR && HAVE_BUILTIN_TYPES_COMPATIBLE_P && HAVE_TYPEOF
88 #define cast_sign_compatible(t, e) \
89 __builtin_choose_expr( \
90 __builtin_types_compatible_p(__typeof__(t), char *) || \
91 __builtin_types_compatible_p(__typeof__(t), signed char *) || \
92 __builtin_types_compatible_p(__typeof__(t), unsigned char *), \
93 /* if type is not const qualified */ \
94 __builtin_types_compatible_p(__typeof__(e), char *) || \
95 __builtin_types_compatible_p(__typeof__(e), signed char *) || \
96 __builtin_types_compatible_p(__typeof__(e), unsigned char *), \
97 /* and if it is... */ \
98 __builtin_types_compatible_p(__typeof__(e), const char *) || \
99 __builtin_types_compatible_p(__typeof__(e), const signed char *) || \
100 __builtin_types_compatible_p(__typeof__(e), const unsigned char *) ||\
101 __builtin_types_compatible_p(__typeof__(e), char *) || \
102 __builtin_types_compatible_p(__typeof__(e), signed char *) || \
103 __builtin_types_compatible_p(__typeof__(e), unsigned char *) \
106 #define cast_const_strip1(expr) \
107 __typeof__(*(struct { int z; __typeof__(expr) x; }){0}.x)
108 #define cast_const_strip2(expr) \
109 __typeof__(**(struct { int z; __typeof__(expr) x; }){0}.x)
110 #define cast_const_strip3(expr) \
111 __typeof__(***(struct { int z; __typeof__(expr) x; }){0}.x)
112 #define cast_const_compat1(expr, type) \
113 __builtin_types_compatible_p(cast_const_strip1(expr), \
114 cast_const_strip1(type))
115 #define cast_const_compat2(expr, type) \
116 __builtin_types_compatible_p(cast_const_strip2(expr), \
117 cast_const_strip2(type))
118 #define cast_const_compat3(expr, type) \
119 __builtin_types_compatible_p(cast_const_strip3(expr), \
120 cast_const_strip3(type))
122 #define cast_sign_compatible(type, expr) \
123 (sizeof(*(type)0) == 1 && sizeof(*(expr)) == 1)
124 #define cast_const_compat1(expr, type) \
125 (sizeof(*(expr)) == sizeof(*(type)0))
126 #define cast_const_compat2(expr, type) \
127 (sizeof(**(expr)) == sizeof(**(type)0))
128 #define cast_const_compat3(expr, type) \
129 (sizeof(***(expr)) == sizeof(***(type)0))
131 #endif /* CCAN_CAST_H */