É uma coisa que se deve a como o C começou a ser desenvolvido.
No início o C não tinha void, logo todas as funções retornavam qualquer coisa (normalmente um int), mesmo que esse valor não fosse utilizado. Quando o void foi implementado, não foi feito sem valor de retorno, pelo contrário, continua a apontar para um espaço de memória que contém lá qualquer coisa, que não foi modificada.
Para um programa que vai criar um processo filho, o retorno desse processo será o retorno da função main, que se for void, vai ser um valor "aleatório", que por acaso se encontrava em memória naquela altura.
No caso de o sistema operativo lançar um programa que tenha sido programado com void main(), quando esse programa termina, o sistema operativo vai receber o valor, podendo considerar o retorno como erro, considerando que o programa falhou e registando nos logs, informando o utilizador,... Entre outras coisas "feias".
Por isso foi criado o standard C99, que "obriga" a que o main retorne um int. Os compiladores que seguem este standard (que são práticamente todos hoje em dia), dão warning quando encontram a função main a retornar void. Continuam a permitir, mas avisam que não deve ser feito.
Existem mais coisas que podem parecer "estranhas" neste standard. Por exemplo, um que eu nunca percebi muito bem é obrigar-nos a colocar uma linha em branco no final de cada ficheiro com código fonte.