The C standard defines which array accesses are valid or not in the C abstract machine. This definition isn’t simple at all. A C implementation can in principle add runtime machinery to check all accesses during execution. C implementations generally don't, due to performance and ABI compatibility reasons. But C the language doesn’t prohibit it. Most existing programs making use of "buffer overflow within a struct" probaby aren't actually conforming C programs.
Yes, one of those "features" designed to work around limitations of the language
C is "simple" in the same way a chainsaw without guards or brakes is "simpler" than one with those attachments