Workarounds for C11 _Generic()
chiark.greenend.org.uk
Workarounds for C11 _Generic()
1–10 of 58 posts
Re: Workarounds for C11 _Generic()
#2So sure, "(x)->length" might not be valid syntax in all configurations the compiler might see. But "LENGTH(x)" is, e.g.:
#if X_MIGHT_BE_MYSTRINGBUFFER
#define LENGTH(x) ((x)->length)
#else
#define LENGTH(x) 0 /* anything that converts to the output type will do */
#endif
This is a routine pattern seen everywhere in C. The Linux kernel is filled with it, e.g. field accessors or arch-specific functions that are stubbed out when not needed, etc...Is this as clean as a full-on generic typesystem? No. But it's C, it shows a weirdness that you have to handle manually, and you do it the same way we've been doing it in C for decades. Not a new problem, doesn't need a new solution. It's C!
Re: Workarounds for C11 _Generic()
#3Re: Workarounds for C11 _Generic()
#4According to this the "big bug" is that... _Generic works mostly like a macro and expands code that the compiler sees. That seems like a little weak, macros have been doing this forever via a mere extra level of indirection. So sure, "(x)->length" might not be valid syntax in all configurations the compiler might see. But "LENGTH(x)" is, e.g.: #if X_MIGHT_BE_MYSTRINGBUFFER #define LENGTH(x) ((x)->length) #else #defin…
Re: Workarounds for C11 _Generic()
#5 define string_length(x) _Generic(x, \
const char * : strlen((const char*)(const void*)x), \
struct MyStringBuffer * : ((const MyStringBuffer*)(const void*)x)->length)Re: Workarounds for C11 _Generic()
#6Will this work? define string_length(x) _Generic(x, \ const char * : strlen((const char*)(const void*)x), \ struct MyStringBuffer * : ((const MyStringBuffer*)(const void*)x)->length)
Re: Workarounds for C11 _Generic()
#7According to this the "big bug" is that... _Generic works mostly like a macro and expands code that the compiler sees. That seems like a little weak, macros have been doing this forever via a mere extra level of indirection. So sure, "(x)->length" might not be valid syntax in all configurations the compiler might see. But "LENGTH(x)" is, e.g.: #if X_MIGHT_BE_MYSTRINGBUFFER #define LENGTH(x) ((x)->length) #else #defin…
Your #if statement will select exactly one implementation for every single site of the use of LENGTH() in the codebase, depending on the value of X_MIGHT_BE_MYSTRINGBUFFER at compile-time.
_Generic() allows you to have both implementations available, and different implementations can be selected at the call site depending on the type of the argument passed.
Re: Workarounds for C11 _Generic()
#8Re: Workarounds for C11 _Generic()
#9Maybe C just shouldn't include generics. Especially not as part of the macro layer.
Re: Workarounds for C11 _Generic()
#10Not directly related but does some c/c++ compiler implement a combination of flags that create a sort "c with templates" version of C ?