4 ms·
Improving _Generic in C2y
- fanf2 2y agoThe article describes two problems with _Generic. There is a third: the discarded branches must typecheck. (Unlike C++ templates, where substitution failure is not an error.) Simon Tatham described the issue in more detail: https://www.chiark.greenend.org.uk/~sgtatham/quasiblog/c11-generic/ https://www.chiark.greenend.org.uk/~sgtatham/quasiblog/c11-g...
- fweimer 2y agoThere's also the macro expansion/amplification issue (explained at the end of the page you reference). _Generic seems a dead end, it doesn't even work in practice for <tgmath.h>.
- kzrdude 2y agoThat kind of problem of macro expansion was well explored in a recent Lwn article.. Kilobytes long expansions for some simple operations. https://lwn.net/SubscriberLink/983965/1240798fdfe236df/ https://lwn.net/SubscriberLink/983965/1240798fdfe236df/ This merits changes in C too but I don't know what if it's not templates.
- skissane 2y ago> This merits changes in C too but I don't know what if it's not templates. C’s preprocessor is really weak-compared e.g to M4, or the PL/I preprocessor. Yet people manage to do all kinds of amazing tricks with it. The price of those tricks, is a big blowout in preprocessing time. If they added some of the missing features (e.g. conditional macro expansion, iteration), people would be able to achieve the same things with far better performance. Obviously that couldn’t do everything templates could do - even with a much more powerful macro system, macros would still be ignorant of types - and if they became type-aware, they’d essentially be templates by another name. Still, more powerful macros could deliver a lot of benefits (in compilation time and ease of understanding) for real world code bases, even if C templates never happen.
- o11c 2y agoThere's also the fact that the bodies must be expressions, so it's only useful with GNU statement expressions. Still, since we have __VA_OPT__ and typeof, standard C has gotten to the point of being almost usable ...
- fuhsnn 2y agoIn its current form without at least requiring balanced enclosing brackets, dropping the semantic check will make _Generic a new macro expansion system worthy of a dedicated round of obfuscated C contest.
- Conscat 2y agoI tried using `_Generic` inside C++ templates as a lighter alternative to `std::conditional_t`, but I was disappointed to find it didn't have short-circuiting semantics, which is my biggest pain point with `std::conditional_t`. If it wasn't necessary to type-check, that would make variadic programming much easier for me. The other problem is that only Clang accepts it in C++ mode.
- gpderetta 2y agoIf constexpr makes it moot nowadays, but before that there were generic lambda tricks. Fore pure type level programming, it is possible to write lazily evaluated std::conditional. What's your usecase?
- Joker_vD 2y agoThat's... not really a problem when you dispatch on pointer types? Like, to fix the example from the article you quote: #define string_length_fixed(x) _Generic(x, \ const char * : strlen((const char*)(x)), \ struct MyStringBuffer * : ((struct MyStringBuffer *)(x))->length) The discarded branches don't get evaluated so it's perfectly fine.
- ori_b 2y agoThere's a far worse problem: that you effectively need to use it from preprocessor macros, which effectively prevents it from being used from being used in sane interfaces.
- flohofwoe 2y agoThe "interface" would directly expose the specialized and uniquely named functions. _Generic is just an inline helper to automatically select the right specialized function by a type. If C ABI compatibility is required, that's about the only way to do it (for better or worse). (FWIW I haven't found a compelling reason yet to use _Generic in my own C code)
- ori_b 2y agoI don't think there are very many compelling reasons to use it. It's a dead end. If I can use _Generic, I can get a cleaner interface by directly calling the right function, and skipping the macro mess.
- colonwqbang 2y agoNice, does this mean we can have const-generic accesors now? I.e. &s->somefield and get a const pointer if s was a const pointer, but a mutable one otherwise? I guess we still need to define two functions though, but that can probably be handled by macros. This is something that really hinders use of const in current C.
- brcmthrowaway 2y agoWow, I can't believe they wasted a decade on 2 releases Move fast!
- Conscat 2y agoClang, as a non-standard feature, allows you to put a type-id into `_Generic` rather than an expression.
- Conscat 2y agoI am being silenced for speaking the truth! https://github.com/llvm/llvm-project/commit/12728e144994efe84715f4e5dbb8c3104e9f0b5a https://github.com/llvm/llvm-project/commit/12728e144994efe8... https://clang.llvm.org/docs/LanguageExtensions.html#c11-generic-selections https://clang.llvm.org/docs/LanguageExtensions.html#c11-gene...
- ekeane 2y agoPresumably because the article points that out.
- plorkyeran 2y agoYou're being downvoted for very clearly not reading the article as that extension and the fact that it got standardized is what the article is about.
- downvotetruth 2y agoJust be sure to have no regrets.
- deleted 2y ago[deleted]