Norman James | 6a58a27 | 2015-10-07 14:34:16 -0500 | [diff] [blame] | 1 | /* CC0 (Public domain) - see LICENSE file for details */
|
| 2 | #ifndef CCAN_CHECK_TYPE_H
|
| 3 | #define CCAN_CHECK_TYPE_H
|
| 4 | #include "config.h"
|
| 5 |
|
| 6 | /**
|
| 7 | * check_type - issue a warning or build failure if type is not correct.
|
| 8 | * @expr: the expression whose type we should check (not evaluated).
|
| 9 | * @type: the exact type we expect the expression to be.
|
| 10 | *
|
| 11 | * This macro is usually used within other macros to try to ensure that a macro
|
| 12 | * argument is of the expected type. No type promotion of the expression is
|
| 13 | * done: an unsigned int is not the same as an int!
|
| 14 | *
|
| 15 | * check_type() always evaluates to 0.
|
| 16 | *
|
| 17 | * If your compiler does not support typeof, then the best we can do is fail
|
| 18 | * to compile if the sizes of the types are unequal (a less complete check).
|
| 19 | *
|
| 20 | * Example:
|
| 21 | * // They should always pass a 64-bit value to _set_some_value!
|
| 22 | * #define set_some_value(expr) \
|
| 23 | * _set_some_value((check_type((expr), uint64_t), (expr)))
|
| 24 | */
|
| 25 |
|
| 26 | /**
|
| 27 | * check_types_match - issue a warning or build failure if types are not same.
|
| 28 | * @expr1: the first expression (not evaluated).
|
| 29 | * @expr2: the second expression (not evaluated).
|
| 30 | *
|
| 31 | * This macro is usually used within other macros to try to ensure that
|
| 32 | * arguments are of identical types. No type promotion of the expressions is
|
| 33 | * done: an unsigned int is not the same as an int!
|
| 34 | *
|
| 35 | * check_types_match() always evaluates to 0.
|
| 36 | *
|
| 37 | * If your compiler does not support typeof, then the best we can do is fail
|
| 38 | * to compile if the sizes of the types are unequal (a less complete check).
|
| 39 | *
|
| 40 | * Example:
|
| 41 | * // Do subtraction to get to enclosing type, but make sure that
|
| 42 | * // pointer is of correct type for that member.
|
| 43 | * #define container_of(mbr_ptr, encl_type, mbr) \
|
| 44 | * (check_types_match((mbr_ptr), &((encl_type *)0)->mbr), \
|
| 45 | * ((encl_type *) \
|
| 46 | * ((char *)(mbr_ptr) - offsetof(enclosing_type, mbr))))
|
| 47 | */
|
| 48 | #if HAVE_TYPEOF
|
| 49 | #define check_type(expr, type) \
|
| 50 | ((typeof(expr) *)0 != (type *)0)
|
| 51 |
|
| 52 | #define check_types_match(expr1, expr2) \
|
| 53 | ((typeof(expr1) *)0 != (typeof(expr2) *)0)
|
| 54 | #else
|
| 55 | #include <ccan/build_assert/build_assert.h>
|
| 56 | /* Without typeof, we can only test the sizes. */
|
| 57 | #define check_type(expr, type) \
|
| 58 | BUILD_ASSERT_OR_ZERO(sizeof(expr) == sizeof(type))
|
| 59 |
|
| 60 | #define check_types_match(expr1, expr2) \
|
| 61 | BUILD_ASSERT_OR_ZERO(sizeof(expr1) == sizeof(expr2))
|
| 62 | #endif /* HAVE_TYPEOF */
|
| 63 |
|
| 64 | #endif /* CCAN_CHECK_TYPE_H */
|