Skip to content

Instantly share code, notes, and snippets.

@m1lkweed
Last active May 24, 2024 06:31
Show Gist options
  • Save m1lkweed/867c4484cf08d56a85ec3ae59596a8f7 to your computer and use it in GitHub Desktop.
Save m1lkweed/867c4484cf08d56a85ec3ae59596a8f7 to your computer and use it in GitHub Desktop.
Replacements for various gcc builtins using c23's `typeof` and c11's `_Generic`
// Compares types of both parameters. Returns true if the types are compatible, otherwise false.
// Parameter y may not be a variably-modified type.
// Designed to be a drop-in replacement for gcc's __builtin_types_compatible_p
#define types_compatible_p(x, y) _Generic(((typeof_unqual(x)*){}), typeof_unqual(y)*:1, default:0)
// Cast the bits of arg to type. Parameter type must be a type and must not be a literal or object with that type.
// Designed to be compatible with g++'s __builtin_bit_cast
#define bit_cast(type, ...) ( \
union{typeof(__VA_ARGS__) in; typeof(type) out; \
int enforce_type:_Generic((int(*)(int(type)))0, \
int(*)(int):-1, default:1);} \
){__VA_ARGS__}.out
// Selects between one of two expressions based on a compile-time constant.
// Return type matches the chosen expression. Designed to be a drop-in replacement for gcc's __builtin_choose_expr
#define choose_expr(cond, truthy, falsy) _Generic((int(*)[1 + !!(cond)])0, int(*)[2]: truthy, int(*)[1]: falsy)
// Returns true if argument is a constant expression, otherwise false.
// This is NOT a drop-in replacement for gcc's __builtin_constant_p as it cannot handle structs.
#define constant_p(...) _Generic((int(*)[1 + !(__VA_ARGS__)])0, int(*)[3]:0, default:1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment