But that's the thing, it can.
- you can specify compile-time preconditions and use the type system to ensure value are in range (which catches a ton of errors) - you can use constexpr to enforce no UB (UB in constexpr evaluation is a compile error)
For instance, it's trivial to make a type-checked db id in c++ which will give you a hard error if you use the id pertaining to a given type, to another type. That's much harder to do in C (without implementing a custom code generator at least that would basically reimplement templates) and has saved me lots of very costly hours of debugging when I see the amount of time I got compile errors I got from that.