Por que o comportamento indefinido é permitido em C

Eu tenho andado brincando tentando aprender C ultimamente. Vindo de Java, me surpreendeu que você possa executar determinadas operações declaradas como "indefinidas".

Isso me parece extremamente inseguro. Entendo que é responsabilidade do programador não executar operações indefinidas, mas por que é permitido começar? Por que o compilador não captura, por exemplo, índices de matriz fora dos limites ou mesmo ponteiros pendentes? Você acaba acessando blocos de memória que nunca deve acessar, sem um motivo aparente.

Como comparação, Java fazcerteza absoluta você não fazqualquer coisa estúpido, lançando exceções como bolos quentes.

Certamente deve haver uma razão pela qual isso é permitido? O que é isso?

RESPOSTA: Para meu entendimento, a principal razão é o desempenho. Além disso, o Java tem comportamentos indefinidos, embora não rotulados como tal.

EDIT: pergunta restrita a C