There's a lot of post-C99 that has somewhat questionable value (_Generic is very much a we-have-templates-at-home kind of feature), but there are some post-C99 features that I'm rather happy to have:
* thread_local and _Atomic support from C11
* fopen("foo", "x") from C11
* aligned_alloc from C11
* CMPLX macro from C11
* C++ attribute syntax ([[foo]] flows better to me than __attribute__((foo)) does)
* C23 finally gets rid of _Who _The _Hell _Thinks _Users _Like _This-style _Keywords.
* Multi-level break/continue in C2y
* Variable declarations in if conditions.
* Some of the new operations like ckd_add or stdc_rotate_left. I do dislike the names, but meh, at least C is starting to gain a competent set of fundamental operations.
It doesn't get rid of _Really_Hate_This, only for a few that already have enough years behind them, the process for new keywords remains the same.
Bounded checked slices like proposed by Dennis Ritchie, or Walter Bright, remains a pipe dream.
> C23 finally gets rid of _Who _The _Hell _Thinks _Users _Like _This-style _Keywords.
I always took those to mean "we're sure a bunch of you are already using the keyword we wanted to use as typedef in your codebase, so here's something that's in the standard's namespace, and you can typedef it to something sane for your codebase".
Also, C23 (and C2y) is moving ever closer to actually having defined semantics. As in, "just because one branch of your code, for this particular input, has read a value out of an array's bounds, your whole program's execution doesn't suddenly rewinds back to the start (with I/O included) and NOPs/loops infinitely/executes random bytes after main()".
Also, I'm personally still waiting for a "shift left" operator having cleaner wording in the standard:
What does "otherwise" means here? It can't mean "if E1 has an unsigned type, or negative value, or E1 × 2**E2 is unrepresentable, then the behavior is undefined" because the part "if E1 has an unsigned type" has already been covered by the previous clause. Does it mean "If E1 has negative value, or E1 × 2**E2 is unrepresentable, then the behavior is undefined"? Because that's a ridiculous ordinance: (-1) << 1 is UB?!