Last active
May 24, 2024 06:31
-
-
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`
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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