I wish C had function overloading and a very basic version of C++ templates. Just enough to get list, vector, map. They could be implemented as templated structs + templated global functions. With just those things would go quite a way. We could avoid writing lists with void* and get type safety instead.
And no, I don’t think that would turn it into C++, you still wouldn’t have namespaces, classes, and virtual functions.
It is my experience that function overloading is a (frankly bad) workaround for lack of a better type system.
For example, Haskell allows for generics and functions that operate on multiple types without overloading by having a more powerful type system (primarily, by having type classes).
In addition, function overloading and name mangling make things a massive pain later on. For example, this is one of the main reasons that it is an epic pain for C code to call C++—incidentally, this is the primary reason that I cannot and do not use Qt.
Honestly, _Generic seems solid in my opinion for simple templates; is it even remotely as powerful? Nope, and I’m okay with that. Actually, in all my time using C, I have yet to find a time where I really found myself wanting generics. I’m much more interested in something like static_assert. To all their own, I suppose :)