You can also use type safety to enforce input validation in C. Just return an error code from the initializer, and annotate it must check. (Or, if you want to couple memory allocation with the checks, write a factory that returns null on input validation errors).
Various parts of the stdlib do this, though often without the compiler annotation. They often hide the struct members inside a compilation unit to prevent callers from bypassing the check (as much as is possible in a language with unsafe primitives).