Compiler Core & Compile-Time Metaprogramming
include/compiler/core.h View source View on GitHubMacros
Section titled “Macros”cc_align_as
Section titled “cc_align_as”#define cc_align_as(x) source Expansion
#define cc_align_as(x) _Alignas(x) cc_alignof
Section titled “cc_alignof”#define cc_alignof(x) source Expansion
#define cc_alignof(x) _Alignof(x) cc_generic
Section titled “cc_generic”#define cc_generic(...) source Expansion
#define cc_generic(...) _Generic(__VA_ARGS__) cc_bitfield_barrier
Section titled “cc_bitfield_barrier”#define cc_bitfield_barrier(t) source clang-format off
Expansion
#define cc_bitfield_barrier(t) t:0 cc_code_init
Section titled “cc_code_init”#define cc_code_init source Nothing for now, TODO:
cc_noinline
Section titled “cc_noinline”#define cc_noinline __attribute__((noinline)) source cc_always_inline
Section titled “cc_always_inline”#define cc_always_inline __attribute__((always_inline)) source cc_noreturn
Section titled “cc_noreturn”#define cc_noreturn __attribute__((noreturn)) source cc_unused
Section titled “cc_unused”#define cc_unused __attribute__((unused)) source cc_maybe_unused
Section titled “cc_maybe_unused”#define cc_maybe_unused __attribute__((unused)) source cc_warn_unused_result
Section titled “cc_warn_unused_result”#define cc_warn_unused_result __attribute__((warn_unused_result)) source cc_nodiscard
Section titled “cc_nodiscard”#define cc_nodiscard __attribute__((warn_unused_result)) source cc_packed
Section titled “cc_packed”#define cc_packed __attribute__((__packed__)) source cc_aligned
Section titled “cc_aligned”#define cc_aligned(x) source Expansion
#define cc_aligned(x) __attribute__((aligned(x))) cc_cache_aligned
Section titled “cc_cache_aligned”#define cc_cache_aligned __attribute__((aligned(64))) source cc_used
Section titled “cc_used”#define cc_used __attribute__((used)) source cc_section
Section titled “cc_section”#define cc_section(x) source Expansion
#define cc_section(x) __attribute__((section(x))) cc_hidden
Section titled “cc_hidden”#define cc_hidden __attribute__((visibility("hidden"))) source cc_export
Section titled “cc_export”#define cc_export __attribute__((visibility("default"))) source cc_overloadable
Section titled “cc_overloadable”#define cc_overloadable __attribute__((overloadable)) source cc_likely
Section titled “cc_likely”cc_unlikely
Section titled “cc_unlikely”#define cc_unlikely(x) source Expansion
#define cc_unlikely(x) __builtin_expect(!!(x), 0) cc_unreachable
Section titled “cc_unreachable”#define cc_unreachable() source Expansion
#define cc_unreachable() __builtin_unreachable() cc_assume
Section titled “cc_assume”cc_assume
Section titled “cc_assume”cc_assume
Section titled “cc_assume”#define cc_assume(expr) source Expansion
#define cc_assume(expr) \
do { \
if (!(expr)) \
__builtin_unreachable(); \
} while (0) cc_cold
Section titled “cc_cold”#define cc_cold __attribute__((cold)) source cc_hot
Section titled “cc_hot”#define cc_hot __attribute__((hot)) source cc_flatten
Section titled “cc_flatten”#define cc_flatten __attribute__((flatten)) source cc_nodebug
Section titled “cc_nodebug”#define cc_nodebug __attribute__((nodebug)) source cc_nodebug
Section titled “cc_nodebug”#define cc_nodebug source cc_no_asan
Section titled “cc_no_asan”#define cc_no_asan __attribute__((no_sanitize("address"))) source cc_no_ubsan
Section titled “cc_no_ubsan”#define cc_no_ubsan __attribute__((no_sanitize("undefined"))) source cc_no_tsan
Section titled “cc_no_tsan”#define cc_no_tsan __attribute__((no_sanitize("thread"))) source cc_no_msan
Section titled “cc_no_msan”#define cc_no_msan __attribute__((no_sanitize("memory"))) source cc_no_csan
Section titled “cc_no_csan”#define cc_no_csan __attribute__((no_sanitize("coverage"))) source cc_no_msan
Section titled “cc_no_msan”#define cc_no_msan source GCC has no MSan
cc_no_csan
Section titled “cc_no_csan”#define cc_no_csan __attribute__((no_sanitize_coverage)) source cc_no_msan
Section titled “cc_no_msan”#define cc_no_msan source cc_no_csan
Section titled “cc_no_csan”#define cc_no_csan source cc_no_sanitize
Section titled “cc_no_sanitize”#define cc_no_sanitize(...) source Expansion
#define cc_no_sanitize(...) __attribute__((no_sanitize(__VA_ARGS__))) cc_no_stack_protector
Section titled “cc_no_stack_protector”#define cc_no_stack_protector __attribute__((no_stack_protector)) source cc_no_instrument
Section titled “cc_no_instrument”#define cc_no_instrument __attribute__((no_instrument_function)) source cc_deprecated
Section titled “cc_deprecated”#define cc_deprecated __attribute__((deprecated)) source cc_deprecated_msg
Section titled “cc_deprecated_msg”Expansion
#define cc_deprecated_msg(msg) __attribute__((deprecated(msg))) cc_pure
Section titled “cc_pure”#define cc_pure __attribute__((pure)) source cc_constfn
Section titled “cc_constfn”#define cc_constfn __attribute__((const)) source cc_noclone
Section titled “cc_noclone”#define cc_noclone __attribute__((noclone)) source cc_malloc_like
Section titled “cc_malloc_like”#define cc_malloc_like __attribute__((malloc)) source cc_naked
Section titled “cc_naked”#define cc_naked __attribute__((naked)) source cc_interrupt
Section titled “cc_interrupt”#define cc_interrupt __attribute__((interrupt)) source cc_no_caller_saved_registers
Section titled “cc_no_caller_saved_registers”#define cc_no_caller_saved_registers __attribute__((no_caller_saved_registers)) source cc_returns_nonnull
Section titled “cc_returns_nonnull”#define cc_returns_nonnull __attribute__((returns_nonnull)) source cc_returns_twice
Section titled “cc_returns_twice”#define cc_returns_twice __attribute__((returns_twice)) source cc_may_alias
Section titled “cc_may_alias”#define cc_may_alias __attribute__((__may_alias__)) source cc_weak
Section titled “cc_weak”#define cc_weak __attribute__((weak)) source cc_weakref
Section titled “cc_weakref”#define cc_weakref(sym) source Expansion
#define cc_weakref(sym) __attribute__((weakref(#sym))) cc_alias
Section titled “cc_alias”cc_alloc_size
Section titled “cc_alloc_size”#define cc_alloc_size(...) source Expansion
#define cc_alloc_size(...) __attribute__((alloc_size(__VA_ARGS__))) cc_alloc_align
Section titled “cc_alloc_align”#define cc_alloc_align(param_idx) source Expansion
#define cc_alloc_align(param_idx) __attribute__((alloc_align(param_idx))) cc_nullable
Section titled “cc_nullable”#define cc_nullable _Nullable source cc_nonnull_ptr
Section titled “cc_nonnull_ptr”#define cc_nonnull_ptr _Nonnull source cc_nullable
Section titled “cc_nullable”#define cc_nullable source cc_nonnull_ptr
Section titled “cc_nonnull_ptr”#define cc_nonnull_ptr source cc_dealloc
Section titled “cc_dealloc”#define cc_dealloc(fn, arg_idx) source Expansion
#define cc_dealloc(fn, arg_idx) __attribute__((malloc(fn, arg_idx))) cc_dealloc
Section titled “cc_dealloc”#define cc_dealloc(fn, arg_idx) source Expansion
#define cc_dealloc(fn, arg_idx) cc_owner_returns
Section titled “cc_owner_returns”#define cc_owner_returns(tag, ...) source Expansion
#define cc_owner_returns(tag, ...) \
__attribute__((ownership_returns(tag, ##__VA_ARGS__))) cc_owner_takes
Section titled “cc_owner_takes”#define cc_owner_takes(tag, arg_idx) source Expansion
#define cc_owner_takes(tag, arg_idx) \
__attribute__((ownership_takes(tag, arg_idx))) cc_owner_returns
Section titled “cc_owner_returns”#define cc_owner_returns(tag, ...) source Expansion
#define cc_owner_returns(tag, ...) cc_owner_takes
Section titled “cc_owner_takes”#define cc_owner_takes(tag, arg_idx) source Expansion
#define cc_owner_takes(tag, arg_idx) cc_analyzer_noreturn
Section titled “cc_analyzer_noreturn”#define cc_analyzer_noreturn __attribute__((analyzer_noreturn)) source cc_analyzer_noreturn
Section titled “cc_analyzer_noreturn”#define cc_analyzer_noreturn source cc_error
Section titled “cc_error”cc_warning
Section titled “cc_warning”Expansion
#define cc_warning(msg) __attribute__((warning(msg))) cc_nonnull
Section titled “cc_nonnull”#define cc_nonnull(...) source Expansion
#define cc_nonnull(...) __attribute__((nonnull(__VA_ARGS__))) cc_counted_by
Section titled “cc_counted_by”#define cc_counted_by(member) source Expansion
#define cc_counted_by(member) __attribute__((counted_by(member))) cc_counted_by
Section titled “cc_counted_by”#define cc_counted_by(member) source Expansion
#define cc_counted_by(member) cc_counted_by_or_null
Section titled “cc_counted_by_or_null”#define cc_counted_by_or_null(member) source Expansion
#define cc_counted_by_or_null(member) \
__attribute__((counted_by_or_null(member))) cc_counted_by_or_null
Section titled “cc_counted_by_or_null”#define cc_counted_by_or_null(member) source Expansion
#define cc_counted_by_or_null(member) cc_sized_by
Section titled “cc_sized_by”#define cc_sized_by(member) source Expansion
#define cc_sized_by(member) __attribute__((sized_by(member))) cc_sized_by
Section titled “cc_sized_by”#define cc_sized_by(member) source Expansion
#define cc_sized_by(member) cc_sized_by_or_null
Section titled “cc_sized_by_or_null”#define cc_sized_by_or_null(member) source Expansion
#define cc_sized_by_or_null(member) __attribute__((sized_by_or_null(member))) cc_sized_by_or_null
Section titled “cc_sized_by_or_null”#define cc_sized_by_or_null(member) source Expansion
#define cc_sized_by_or_null(member) cc_pass_object_size
Section titled “cc_pass_object_size”#define cc_pass_object_size(type) source Expansion
#define cc_pass_object_size(type) __attribute__((pass_object_size(type))) cc_pass_object_size
Section titled “cc_pass_object_size”#define cc_pass_object_size(type) source Expansion
#define cc_pass_object_size(type) cc_diagnose_if
Section titled “cc_diagnose_if”Expansion
#define cc_diagnose_if(cond, msg, severity) \
__attribute__((diagnose_if(cond, msg, severity))) cc_diagnose_if
Section titled “cc_diagnose_if”Expansion
#define cc_diagnose_if(cond, msg, severity) ct_precond
Section titled “ct_precond”#define ct_precond(...) source void take(void *p, unsigned flags, size_t n) ct_precond(p != NULL) ct_precond(flags & F_A, “use take_noflag() when F_A is clear”) ct_precond(n <= 4096);
Notably only is able to check constants passed in.
enforce_precond() for runtime precondition validation
Expansion
#define ct_precond(...) \
PP_CONCAT(_ct_precond_, PP_NARG(__VA_ARGS__))(__VA_ARGS__) _ct_precond_1
Section titled “_ct_precond_1”#define _ct_precond_1(cond) source Expansion
#define _ct_precond_1(cond) \
cc_diagnose_if(!(cond), "precondition violated: " #cond, "error") _ct_precond_2
Section titled “_ct_precond_2”#define _ct_precond_2(cond, hint) source Expansion
#define _ct_precond_2(cond, hint) \
cc_diagnose_if(!(cond), "precondition violated: " #cond " -- " hint, \
"error") cc_enable_if
Section titled “cc_enable_if”Expansion
#define cc_enable_if(cond, msg) __attribute__((enable_if(cond, msg))) cc_enable_if
Section titled “cc_enable_if”Expansion
#define cc_enable_if(cond, msg) cc_access
Section titled “cc_access”#define cc_access(mode, ...) source Expansion
#define cc_access(mode, ...) __attribute__((access(mode, __VA_ARGS__))) cc_access
Section titled “cc_access”cc_printf_like
Section titled “cc_printf_like”#define cc_printf_like(fmt_idx, arg_idx) source Expansion
#define cc_printf_like(fmt_idx, arg_idx) \
__attribute__((format(printf, fmt_idx, arg_idx))) cc_constructor
Section titled “cc_constructor”#define cc_constructor(prio) source Expansion
#define cc_constructor(prio) __attribute__((constructor(prio))) cc_destructor
Section titled “cc_destructor”#define cc_destructor(prio) source Expansion
#define cc_destructor(prio) __attribute__((destructor(prio))) cc_fallthrough
Section titled “cc_fallthrough”#define cc_fallthrough __attribute__((fallthrough)) source cc_cleanup
Section titled “cc_cleanup”#define cc_cleanup(fn) source Expansion
#define cc_cleanup(fn) __attribute__((cleanup(fn))) cc_target
Section titled “cc_target”cc_optimize
Section titled “cc_optimize”#define cc_optimize(...) source Expansion
#define cc_optimize(...) __attribute__((optimize(__VA_ARGS__))) cc_designated_init
Section titled “cc_designated_init”#define cc_designated_init __attribute__((designated_init)) source cc_uninitialized
Section titled “cc_uninitialized”#define cc_uninitialized __attribute__((uninitialized)) source cc_uninitialized
Section titled “cc_uninitialized”#define cc_uninitialized source cc_nonstring
Section titled “cc_nonstring”#define cc_nonstring __attribute__((nonstring)) source cc_nonstring
Section titled “cc_nonstring”#define cc_nonstring source cc_restrict
Section titled “cc_restrict”#define cc_restrict __restrict__ source cc_restrict
Section titled “cc_restrict”#define cc_restrict source cc_mem
Section titled “cc_mem”cc_mem
Section titled “cc_mem”cc_mem_io
Section titled “cc_mem_io”cc_mem_rcu
Section titled “cc_mem_rcu”#define cc_mem_rcu __attribute__((address_space(2), noderef)) source cc_mem_rcu
Section titled “cc_mem_rcu”#define cc_mem_rcu source cc_mem_any_fn
Section titled “cc_mem_any_fn”#define cc_mem_any_fn __attribute__((address_space(3), noderef)) source cc_mem_any_fn
Section titled “cc_mem_any_fn”#define cc_mem_any_fn source PP_ARG_N
Section titled “PP_ARG_N”#define PP_ARG_N(_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, N, ...) source Expansion
#define PP_ARG_N(_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, N, ...) \
N PP_RSEQ_N
Section titled “PP_RSEQ_N”#define PP_RSEQ_N() source Expansion
#define PP_RSEQ_N() \
63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, \
45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, \
28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, \
11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 PP_NARG_HELPER
Section titled “PP_NARG_HELPER”#define PP_NARG_HELPER(...) source Expansion
#define PP_NARG_HELPER(...) PP_ARG_N(__VA_ARGS__) PP_NARG
Section titled “PP_NARG”#define PP_NARG(...) source Expansion
#define PP_NARG(...) PP_NARG_HELPER(_, ##__VA_ARGS__, PP_RSEQ_N()) PP_DISPATCH_
Section titled “PP_DISPATCH_”#define PP_DISPATCH_(name, n) source Expansion
#define PP_DISPATCH_(name, n) name##_##n PP_DISPATCH
Section titled “PP_DISPATCH”#define PP_DISPATCH(name, n) source Expansion
#define PP_DISPATCH(name, n) PP_DISPATCH_(name, n) PP_OVERLOAD
Section titled “PP_OVERLOAD”#define PP_OVERLOAD(name, ...) source Expansion
#define PP_OVERLOAD(name, ...) PP_DISPATCH(name, PP_NARG(__VA_ARGS__)) PP_CALL
Section titled “PP_CALL”#define PP_CALL(name, ...) source Expansion
#define PP_CALL(name, ...) PP_OVERLOAD(name, __VA_ARGS__)(__VA_ARGS__) PP_OVERLOAD2
Section titled “PP_OVERLOAD2”#define PP_OVERLOAD2(name, ...) source The 2 and 3 variants are used when a PP_CALL wants to expand a PP_CALL (first layer), and when a PP_CALL2 wants to expand a PP_CALL or PP_CALL2 (second layer). If anyone wants another layer, they should probably restructure their code
Expansion
#define PP_OVERLOAD2(name, ...) PP_DISPATCH(name, PP_NARG(__VA_ARGS__)) PP_CALL2
Section titled “PP_CALL2”#define PP_CALL2(name, ...) source Expansion
#define PP_CALL2(name, ...) PP_OVERLOAD2(name, __VA_ARGS__)(__VA_ARGS__) PP_OVERLOAD3
Section titled “PP_OVERLOAD3”#define PP_OVERLOAD3(name, ...) source Expansion
#define PP_OVERLOAD3(name, ...) PP_DISPATCH(name, PP_NARG(__VA_ARGS__)) PP_CALL3
Section titled “PP_CALL3”#define PP_CALL3(name, ...) source Expansion
#define PP_CALL3(name, ...) PP_OVERLOAD3(name, __VA_ARGS__)(__VA_ARGS__) PP_CONCAT_
Section titled “PP_CONCAT_”#define PP_CONCAT_(a, b) source Expansion
#define PP_CONCAT_(a, b) a##b PP_CONCAT
Section titled “PP_CONCAT”#define PP_CONCAT(a, b) source Expansion
#define PP_CONCAT(a, b) PP_CONCAT_(a, b) PP_STRINGIZE_
Section titled “PP_STRINGIZE_”#define PP_STRINGIZE_(x) source Expansion
#define PP_STRINGIZE_(x) #x PP_STRINGIZE
Section titled “PP_STRINGIZE”#define PP_STRINGIZE(x) source Expansion
#define PP_STRINGIZE(x) PP_STRINGIZE_(x) PP_EXPAND
Section titled “PP_EXPAND”PP_GET_1
Section titled “PP_GET_1”PP_GET_2
Section titled “PP_GET_2”PP_GET_3
Section titled “PP_GET_3”PP_GET_4
Section titled “PP_GET_4”PP_GET_5
Section titled “PP_GET_5”PP_ARG
Section titled “PP_ARG”PP_DROP_1
Section titled “PP_DROP_1”PP_DROP_2
Section titled “PP_DROP_2”PP_DROP_3
Section titled “PP_DROP_3”PP_DROP_4
Section titled “PP_DROP_4”PP_DROP_5
Section titled “PP_DROP_5”#define PP_DROP_5(a, b, c, d, e, ...) source Expansion
#define PP_DROP_5(a, b, c, d, e, ...) __VA_ARGS__ PP_VA_ARGS_AFTER
Section titled “PP_VA_ARGS_AFTER”#define PP_VA_ARGS_AFTER(n, ...) source Expansion
#define PP_VA_ARGS_AFTER(n, ...) PP_CONCAT(PP_DROP_, n)(__VA_ARGS__) Unused argument discarders
PP_CC_VAR_UNUSED_1
Section titled “PP_CC_VAR_UNUSED_1”#define PP_CC_VAR_UNUSED_1(a) source Expansion
#define PP_CC_VAR_UNUSED_1(a) ((void) (a)) PP_CC_VAR_UNUSED_2
Section titled “PP_CC_VAR_UNUSED_2”#define PP_CC_VAR_UNUSED_2(a, b) source Expansion
#define PP_CC_VAR_UNUSED_2(a, b) (PP_CC_VAR_UNUSED_1(a), (void) (b)) PP_CC_VAR_UNUSED_3
Section titled “PP_CC_VAR_UNUSED_3”#define PP_CC_VAR_UNUSED_3(a, b, c) source Expansion
#define PP_CC_VAR_UNUSED_3(a, b, c) (PP_CC_VAR_UNUSED_2(a, b), (void) (c)) PP_CC_VAR_UNUSED_4
Section titled “PP_CC_VAR_UNUSED_4”#define PP_CC_VAR_UNUSED_4(a, b, c, d) source Expansion
#define PP_CC_VAR_UNUSED_4(a, b, c, d) (PP_CC_VAR_UNUSED_3(a, b, c), (void) (d)) PP_CC_VAR_UNUSED_5
Section titled “PP_CC_VAR_UNUSED_5”#define PP_CC_VAR_UNUSED_5(a, b, c, d, e) source Expansion
#define PP_CC_VAR_UNUSED_5(a, b, c, d, e) \
(PP_CC_VAR_UNUSED_4(a, b, c, d), (void) (e)) PP_CC_VAR_UNUSED_6
Section titled “PP_CC_VAR_UNUSED_6”#define PP_CC_VAR_UNUSED_6(a, b, c, d, e, f) source Expansion
#define PP_CC_VAR_UNUSED_6(a, b, c, d, e, f) \
(PP_CC_VAR_UNUSED_5(a, b, c, d, e), (void) (f)) PP_CC_VAR_UNUSED_7
Section titled “PP_CC_VAR_UNUSED_7”#define PP_CC_VAR_UNUSED_7(a, b, c, d, e, f, g) source Expansion
#define PP_CC_VAR_UNUSED_7(a, b, c, d, e, f, g) \
(PP_CC_VAR_UNUSED_6(a, b, c, d, e, f), (void) (g)) PP_CC_VAR_UNUSED_8
Section titled “PP_CC_VAR_UNUSED_8”#define PP_CC_VAR_UNUSED_8(a, b, c, d, e, f, g, h) source Expansion
#define PP_CC_VAR_UNUSED_8(a, b, c, d, e, f, g, h) \
(PP_CC_VAR_UNUSED_7(a, b, c, d, e, f, g), (void) (h)) PP_UNPAREN
Section titled “PP_UNPAREN”#define PP_UNPAREN(x) source Expansion
#define PP_UNPAREN(x) PP_UNPAREN_ESC_(PP_UNPAREN_ISH_ x) PP_UNPAREN_ISH_
Section titled “PP_UNPAREN_ISH_”#define PP_UNPAREN_ISH_(...) source Expansion
#define PP_UNPAREN_ISH_(...) PP_UNPAREN_ISH_ __VA_ARGS__ PP_UNPAREN_ESC_
Section titled “PP_UNPAREN_ESC_”#define PP_UNPAREN_ESC_(...) source Expansion
#define PP_UNPAREN_ESC_(...) PP_UNPAREN_ESC__(__VA_ARGS__) PP_UNPAREN_ESC__
Section titled “PP_UNPAREN_ESC__”#define PP_UNPAREN_ESC__(...) source Expansion
#define PP_UNPAREN_ESC__(...) PP_UNPAREN_VAN_##__VA_ARGS__ PP_UNPAREN_VAN_PP_UNPAREN_ISH_
Section titled “PP_UNPAREN_VAN_PP_UNPAREN_ISH_”#define PP_UNPAREN_VAN_PP_UNPAREN_ISH_ source PP_IS_PAREN
Section titled “PP_IS_PAREN”#define PP_IS_PAREN(x) source 1 if x is parenthesized, else 0
Expansion
#define PP_IS_PAREN(x) PP_IS_PAREN_N_(PP_IS_PAREN_PROBE_ x, 0, ~) PP_IS_PAREN_PROBE_
Section titled “PP_IS_PAREN_PROBE_”#define PP_IS_PAREN_PROBE_(...) source Expansion
#define PP_IS_PAREN_PROBE_(...) ~, 1, PP_IS_PAREN_N_
Section titled “PP_IS_PAREN_N_”#define PP_IS_PAREN_N_(...) source Expansion
#define PP_IS_PAREN_N_(...) PP_IS_PAREN_PICK_(__VA_ARGS__) PP_IS_PAREN_PICK_
Section titled “PP_IS_PAREN_PICK_”#define PP_IS_PAREN_PICK_(x, n, ...) source Expansion
#define PP_IS_PAREN_PICK_(x, n, ...) n PP_IIF
Section titled “PP_IIF”#define PP_IIF(c) source PP_IIF_0
Section titled “PP_IIF_0”PP_IIF_1
Section titled “PP_IIF_1”PP_FOREACH_CTX
Section titled “PP_FOREACH_CTX”#define PP_FOREACH_CTX(m, c, ...) source Expansion
#define PP_FOREACH_CTX(m, c, ...) \
PP_CONCAT(PP_FE_, PP_NARG(__VA_ARGS__))(m, c, __VA_ARGS__) PP_FE_0
Section titled “PP_FE_0”PP_FE_1
Section titled “PP_FE_1”PP_FE_2
Section titled “PP_FE_2”#define PP_FE_2(m, c, x, ...) source PP_FE_3
Section titled “PP_FE_3”#define PP_FE_3(m, c, x, ...) source PP_FE_4
Section titled “PP_FE_4”#define PP_FE_4(m, c, x, ...) source PP_FE_5
Section titled “PP_FE_5”#define PP_FE_5(m, c, x, ...) source PP_FE_6
Section titled “PP_FE_6”#define PP_FE_6(m, c, x, ...) source PP_FE_7
Section titled “PP_FE_7”#define PP_FE_7(m, c, x, ...) source PP_FE_8
Section titled “PP_FE_8”#define PP_FE_8(m, c, x, ...) source PP_FE_9
Section titled “PP_FE_9”#define PP_FE_9(m, c, x, ...) source PP_FE_10
Section titled “PP_FE_10”#define PP_FE_10(m, c, x, ...) source PP_FE_11
Section titled “PP_FE_11”#define PP_FE_11(m, c, x, ...) source PP_FE_12
Section titled “PP_FE_12”#define PP_FE_12(m, c, x, ...) source PP_FE_13
Section titled “PP_FE_13”#define PP_FE_13(m, c, x, ...) source PP_FE_14
Section titled “PP_FE_14”#define PP_FE_14(m, c, x, ...) source PP_FE_15
Section titled “PP_FE_15”#define PP_FE_15(m, c, x, ...) source PP_FE_16
Section titled “PP_FE_16”#define PP_FE_16(m, c, x, ...) source PP_FE_17
Section titled “PP_FE_17”#define PP_FE_17(m, c, x, ...) source PP_FE_18
Section titled “PP_FE_18”#define PP_FE_18(m, c, x, ...) source PP_FE_19
Section titled “PP_FE_19”#define PP_FE_19(m, c, x, ...) source PP_FE_20
Section titled “PP_FE_20”#define PP_FE_20(m, c, x, ...) source PP_FE_21
Section titled “PP_FE_21”#define PP_FE_21(m, c, x, ...) source PP_FE_22
Section titled “PP_FE_22”#define PP_FE_22(m, c, x, ...) source PP_FE_23
Section titled “PP_FE_23”#define PP_FE_23(m, c, x, ...) source PP_FE_24
Section titled “PP_FE_24”#define PP_FE_24(m, c, x, ...) source PP_FE_25
Section titled “PP_FE_25”#define PP_FE_25(m, c, x, ...) source PP_FE_26
Section titled “PP_FE_26”#define PP_FE_26(m, c, x, ...) source PP_FE_27
Section titled “PP_FE_27”#define PP_FE_27(m, c, x, ...) source PP_FE_28
Section titled “PP_FE_28”#define PP_FE_28(m, c, x, ...) source PP_FE_29
Section titled “PP_FE_29”#define PP_FE_29(m, c, x, ...) source PP_FE_30
Section titled “PP_FE_30”#define PP_FE_30(m, c, x, ...) source PP_FE_31
Section titled “PP_FE_31”#define PP_FE_31(m, c, x, ...) source PP_FE_32
Section titled “PP_FE_32”#define PP_FE_32(m, c, x, ...) source cc_ignore
Section titled “cc_ignore”#define cc_ignore(...) source cc_discard
Section titled “cc_discard”#define cc_discard(expr) source Expansion
#define cc_discard(expr) \
({ \
__auto_type _cc_discard_ = (expr); \
(void) _cc_discard_; \
}) static_assert_1
Section titled “static_assert_1”#define static_assert_1(cond) source Expansion
#define static_assert_1(cond) _Static_assert(cond, #cond) static_assert_2
Section titled “static_assert_2”Expansion
#define static_assert_2(cond, msg) _Static_assert(cond, msg) static_assert
Section titled “static_assert”#define static_assert(...) source Expansion
#define static_assert(...) PP_CALL2(static_assert, __VA_ARGS__) ct_assert_size
Section titled “ct_assert_size”#define ct_assert_size(type, size) source Expansion
#define ct_assert_size(type, size) \
static_assert(sizeof(type) == (size), "sizeof(" #type ") != " #size) ct_assert_align
Section titled “ct_assert_align”#define ct_assert_align(type, align) source Expansion
#define ct_assert_align(type, align) \
static_assert(cc_alignof(type) == (align), "alignof(" #type ") " \
"!= " #align) ct_assert_offset
Section titled “ct_assert_offset”#define ct_assert_offset(type, member, offset) source Expansion
#define ct_assert_offset(type, member, offset) \
static_assert(__builtin_offsetof(type, member) == (offset), \
"offsetof(" #type ", " #member ") != " #offset) ct_assert_same_size
Section titled “ct_assert_same_size”#define ct_assert_same_size(type_a, type_b) source Expansion
#define ct_assert_same_size(type_a, type_b) \
static_assert(sizeof(type_a) == sizeof(type_b), \
"sizeof(" #type_a ") != sizeof(" #type_b ")") ct_assert_struct_size_eq
Section titled “ct_assert_struct_size_eq”#define ct_assert_struct_size_eq(struct_, want_) source Expansion
#define ct_assert_struct_size_eq(struct_, want_) \
ct_assert_size(struct struct_, want_) ct_assert_struct_align_eq
Section titled “ct_assert_struct_align_eq”#define ct_assert_struct_align_eq(struct_, want_) source Expansion
#define ct_assert_struct_align_eq(struct_, want_) \
ct_assert_align(struct struct_, want_) ct_assert_union_size_eq
Section titled “ct_assert_union_size_eq”#define ct_assert_union_size_eq(union_, want_) source Expansion
#define ct_assert_union_size_eq(union_, want_) \
ct_assert_size(union union_, want_) ct_assert_union_align_eq
Section titled “ct_assert_union_align_eq”#define ct_assert_union_align_eq(union_, want_) source Expansion
#define ct_assert_union_align_eq(union_, want_) \
ct_assert_align(union union_, want_) ct_assert_power_of_two
Section titled “ct_assert_power_of_two”#define ct_assert_power_of_two(n) source Expansion
#define ct_assert_power_of_two(n) \
static_assert(((n) > 0 && (((n) & ((n) - 1)) == 0)), \
#n " is not a power of two") ct_assert_nonempty_str
Section titled “ct_assert_nonempty_str”#define ct_assert_nonempty_str(s) source Expansion
#define ct_assert_nonempty_str(s) \
static_assert(sizeof(s) > 1, "empty string: " #s) ct_strong_int
Section titled “ct_strong_int”#define ct_strong_int(stem, STEM, base, max_) source Expansion
#define ct_strong_int(stem, STEM, base, max_) \
typedef enum { \
STEM##_ZERO = 0, \
STEM##_MIN = 0, \
STEM##_MAX = (max_), \
} stem##_t ct_expr_assert_zero
Section titled “ct_expr_assert_zero”Expansion
#define ct_expr_assert_zero(cond, msg) \
(sizeof(struct { \
_Static_assert(__builtin_choose_expr((cond), 1, 0), msg); \
char __ct_pad; \
}) * \
0) ct_expr_assert
Section titled “ct_expr_assert”Expansion
#define ct_expr_assert(cond, msg) ((void) ct_expr_assert_zero(cond, msg)) ct_is_const
Section titled “ct_is_const”#define ct_is_const(x) source Expansion
#define ct_is_const(x) __builtin_constant_p(x) ct_is_ice
Section titled “ct_is_ice”#define ct_is_ice(x) source Expansion
#define ct_is_ice(x) \
(sizeof(int) == sizeof(*(8 ? ((void *) ((long) (x) * 0l)) : (int *) 8))) ct_raw
Section titled “ct_raw”ct_same_type
Section titled “ct_same_type”#define ct_same_type(a, b) source Expansion
#define ct_same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) ct_is_type
Section titled “ct_is_type”#define ct_is_type(T, x) source Expansion
#define ct_is_type(T, x) __builtin_types_compatible_p(T, typeof(x)) ct_is_array
Section titled “ct_is_array”#define ct_is_array(a) source Expansion
#define ct_is_array(a) \
(!__builtin_types_compatible_p(typeof(a), typeof(&(a)[0]))) ct_array_size
Section titled “ct_array_size”#define ct_array_size(a) source Expansion
#define ct_array_size(a) \
(ct_expr_assert_zero(ct_is_array(a), "`" #a "` is a pointer, not an " \
"array; ct_array_size() needs a " \
"real array") + \
(sizeof(a) / sizeof((a)[0]))) ct_const_min
Section titled “ct_const_min”#define ct_const_min(a, b) source Expansion
#define ct_const_min(a, b) __builtin_choose_expr((a) < (b), (a), (b)) ct_const_max
Section titled “ct_const_max”#define ct_const_max(a, b) source Expansion
#define ct_const_max(a, b) __builtin_choose_expr((a) > (b), (a), (b)) ct_const_clamp
Section titled “ct_const_clamp”#define ct_const_clamp(val, min, max) source Expansion
#define ct_const_clamp(val, min, max) ct_const_min(ct_const_max(val, min), max) ct_decay
Section titled “ct_decay”#define ct_decay(x) source Expansion
#define ct_decay(x) typeof(0 ? (x) : ((void) ++(int) {0}, (x))) ct_is_str
Section titled “ct_is_str”#define ct_is_str(x) source ct_as_str
Section titled “ct_as_str”ct_as_type
Section titled “ct_as_type”#define ct_as_type(T, x) source Expansion
#define ct_as_type(T, x) ((T) (uintptr_t) (x)) ct_bitsizeof
Section titled “ct_bitsizeof”#define ct_bitsizeof(x) source Expansion
#define ct_bitsizeof(x) (sizeof(x) * __CHAR_BIT__) ct_type_bitsize
Section titled “ct_type_bitsize”#define ct_type_bitsize(T) source Expansion
#define ct_type_bitsize(T) (sizeof(T) * __CHAR_BIT__) ct_field_sizeof
Section titled “ct_field_sizeof”#define ct_field_sizeof(type, member) source Expansion
#define ct_field_sizeof(type, member) sizeof(((type *) 0)->member) ct_field_offset
Section titled “ct_field_offset”#define ct_field_offset(type, member) source Expansion
#define ct_field_offset(type, member) __builtin_offsetof(type, member) ct_is_pointer
Section titled “ct_is_pointer”#define ct_is_pointer(x) source Expansion
#define ct_is_pointer(x) (__builtin_classify_type(x) == 5) ct_is_fn_ptr
Section titled “ct_is_fn_ptr”#define ct_is_fn_ptr(x) source Expansion
#define ct_is_fn_ptr(x) \
__builtin_types_compatible_p(typeof(&*(x)), typeof(&**(x))) ct_is_integral
Section titled “ct_is_integral”#define ct_is_integral(x) source Expansion
#define ct_is_integral(x) \
(__builtin_classify_type(x) == 1 && \
!__builtin_types_compatible_p(typeof(x), bool)) ct_is_bool
Section titled “ct_is_bool”#define ct_is_bool(x) source Expansion
#define ct_is_bool(x) __builtin_types_compatible_p(typeof(x), _Bool) ct_is_struct
Section titled “ct_is_struct”#define ct_is_struct(x) source Expansion
#define ct_is_struct(x) (__builtin_classify_type(x) == 12) ct_is_union
Section titled “ct_is_union”#define ct_is_union(x) source Expansion
#define ct_is_union(x) (__builtin_classify_type(x) == 13) ct_is_power_of_two
Section titled “ct_is_power_of_two”#define ct_is_power_of_two(n) source Expansion
#define ct_is_power_of_two(n) ((n) > 0 && (((n) & ((n) - 1)) == 0)) ct_type_is_signed
Section titled “ct_type_is_signed”#define ct_type_is_signed(x) source Expansion
#define ct_type_is_signed(x) ((typeof(x)) -1 < (typeof(x)) 1) ct_min_val
Section titled “ct_min_val”#define ct_min_val(T) source Expansion
#define ct_min_val(T) \
((T) (ct_type_is_signed(T) \
? (T) ((__UINTMAX_TYPE__) 1 << (ct_type_bitsize(T) - 1)) \
: (T) 0)) ct_max_val
Section titled “ct_max_val”#define ct_max_val(T) source Expansion
#define ct_max_val(T) \
((T) (ct_type_is_signed(T) \
? (T) (((__UINTMAX_TYPE__) 1 << (ct_type_bitsize(T) - 1)) - 1) \
: (T) ~(T) 0)) ct_typecheck
Section titled “ct_typecheck”#define ct_typecheck(type, x) source Require expr to have the requested type, does not evaluate x
Expansion
#define ct_typecheck(type, x) \
ct_expr_assert(__builtin_types_compatible_p(type, typeof(x)), \
"`" #x "` must have type `" #type "`") ct_typecheck_same
Section titled “ct_typecheck_same”#define ct_typecheck_same(x, y) source Expansion
#define ct_typecheck_same(x, y) \
ct_expr_assert(__builtin_types_compatible_p(typeof(x), typeof(y)), \
"`" #x "` and `" #y "` must have the same type") ct_typecheck_same_unqual
Section titled “ct_typecheck_same_unqual”#define ct_typecheck_same_unqual(x, y) source Expansion
#define ct_typecheck_same_unqual(x, y) \
ct_expr_assert(__builtin_types_compatible_p(__typeof_unqual__(x), \
__typeof_unqual__(y)), \
"`" #x "` and `" #y "` must have the same type") ct_typecheck_integer_as
Section titled “ct_typecheck_integer_as”#define ct_typecheck_integer_as(x, name) source Expansion
#define ct_typecheck_integer_as(x, name) \
ct_expr_assert(ct_is_integral(x), "`" #name "` must have an integer " \
"type ") ct_typecheck_integer
Section titled “ct_typecheck_integer”#define ct_typecheck_integer(x) source Expansion
#define ct_typecheck_integer(x) ct_typecheck_integer_as(x, x) ct_typecheck_signed_as
Section titled “ct_typecheck_signed_as”#define ct_typecheck_signed_as(x, name) source Require x to have a signed integer or enum type
Expansion
#define ct_typecheck_signed_as(x, name) \
(ct_typecheck_integer_as(x, name), \
ct_expr_assert(ct_type_is_signed(x), \
"`" #name "` must have a signed integer type")) ct_typecheck_signed
Section titled “ct_typecheck_signed”#define ct_typecheck_signed(x) source Expansion
#define ct_typecheck_signed(x) ct_typecheck_signed_as(x, x) ct_typecheck_unsigned_as
Section titled “ct_typecheck_unsigned_as”#define ct_typecheck_unsigned_as(x, name) source Require x to have an unsigned integer or enum type
Expansion
#define ct_typecheck_unsigned_as(x, name) \
(ct_typecheck_integer_as(x, name), \
ct_expr_assert(!ct_type_is_signed(x), \
"`" #name "` must have an unsigned integer type")) ct_typecheck_unsigned
Section titled “ct_typecheck_unsigned”#define ct_typecheck_unsigned(x) source Expansion
#define ct_typecheck_unsigned(x) ct_typecheck_unsigned_as(x, x) ct_typecheck_intmax_nonnegative
Section titled “ct_typecheck_intmax_nonnegative”#define ct_typecheck_intmax_nonnegative(x) source Expansion
#define ct_typecheck_intmax_nonnegative(x) \
(((__UINTMAX_TYPE__) (__INTMAX_TYPE__) (x) >> \
(sizeof(__INTMAX_TYPE__) * __CHAR_BIT__ - 1)) == 0) ct_typecheck_source_nonnegative
Section titled “ct_typecheck_source_nonnegative”#define ct_typecheck_source_nonnegative(to, from) source Expansion
#define ct_typecheck_source_nonnegative(to, from) \
(!(ct_type_is_signed(from) && !ct_type_is_signed(to)) || \
ct_typecheck_intmax_nonnegative(from)) ct_typecheck_converted_nonnegative
Section titled “ct_typecheck_converted_nonnegative”#define ct_typecheck_converted_nonnegative(to, from) source Expansion
#define ct_typecheck_converted_nonnegative(to, from) \
(!(!ct_type_is_signed(from) && ct_type_is_signed(to)) || \
ct_typecheck_intmax_nonnegative((typeof(to)) (from))) ct_typecheck_value_fits
Section titled “ct_typecheck_value_fits”#define ct_typecheck_value_fits(to, from) source Expansion
#define ct_typecheck_value_fits(to, from) \
(ct_typecheck_source_nonnegative(to, from) && \
ct_typecheck_converted_nonnegative(to, from) && \
(typeof(from)) ((typeof(to)) (from)) == (typeof(from)) (from)) ct_typecheck_structurally_widenable
Section titled “ct_typecheck_structurally_widenable”#define ct_typecheck_structurally_widenable(to, from) source Whole type widening from signedness and width, always an integer constant expr
Expansion
#define ct_typecheck_structurally_widenable(to, from) \
(((ct_type_is_signed(to) == ct_type_is_signed(from)) && \
sizeof(typeof(from)) <= sizeof(typeof(to))) || \
(ct_type_is_signed(to) && !ct_type_is_signed(from) && \
sizeof(typeof(from)) < sizeof(typeof(to)))) ct_widenable_ok
Section titled “ct_widenable_ok”#define ct_widenable_ok(to, from) source Expansion
#define ct_widenable_ok(to, from) \
__builtin_choose_expr(ct_is_ice(from), \
(ct_typecheck_structurally_widenable(to, from)) || \
(ct_typecheck_value_fits(to, from)), \
(ct_typecheck_structurally_widenable(to, from))) ct_typecheck_widenable_to
Section titled “ct_typecheck_widenable_to”#define ct_typecheck_widenable_to(destination, source) source Require every value of source to be representable by destination, or source to be a constant whose value is representable by the destination. Equal widths require equal signedness, and unsigned sources require wider signed destinations
Expansion
#define ct_typecheck_widenable_to(destination, source) \
(ct_typecheck_integer(destination), ct_typecheck_integer(source), \
ct_expr_assert(ct_widenable_ok(destination, source), \
"`" #source "` cannot be converted to the destination " \
"type without changing its value. cast it explicitly")) ct_common_type_2
Section titled “ct_common_type_2”#define ct_common_type_2(a, b) source Common/larger type to cast up to
Expansion
#define ct_common_type_2(a, b) \
typeof(__builtin_choose_expr(sizeof(typeof(a)) >= sizeof(typeof(b)), (a), \
(b)))