¿Por qué se requiere un prototipo incluso sin ninguna declaración de clase?

Si solo lo hago: Ex1:

#include <iostream>

int main()
{
    //try to call doSomething function
    doSomething();
}

void doSomething()
{
    std::cout << "Call me now!" << std::endl;
}

Me sale un error de compilación! Porque la compilación no sabe qué es "doSomething".

Pero si cambio la posición de doSomething en primer lugar, el programa se compila con éxito. @ Ex2:

#include <iostream>

void doSomething()
{
    std::cout << "Call me now!" << std::endl;
}

int main()
{
    //try to call doSomething function
    doSomething();
}

Puedo declarar que el prototipo es así: Ex3:

#include <iostream>

void doSomething(void);

int main()
{
    //try to call doSomething function
    doSomething();
}

void doSomething()
{
    std::cout << "Call me now!" << std::endl;
}

¿Pero por qué el primer ejemplo no funciona? ¿Por qué incluso tengo que declarar un prototipo o llamar a las funciones primero y a la función principal al final?

¡Gracias

Respuestas a la pregunta(3)

Su respuesta a la pregunta