¿Qué es el mecanismo de declaración de función local C?

La declaración de función local parece estar permitida en gcc, y encontré una discusión sobre esto:¿Hay algún uso para las declaraciones de funciones locales?

Sin embargo, mi pregunta es: ¿está permitido por el estándar ISO C? Si es así, cómo explicar el siguiente fenómeno que lo hace desconcertante:

int main(void) {
    int f(void);
    f();
}
void g(void) {
    /* g has no idea about f. It seems that the decl is limited within its
     * scope */
    f(); 
}
int f(void) {}

mientras

int main(void) {
    int f(void);
    f();
}
void f(void); /* error because disagreement with the local declaration (local
             declaration goes beyound its scope?) */
void f(void) { /* definition here */ }

Según el estándar C99: los nombres de las funciones están en la misma categoría de nombres. Así que discutiremos el mecanismo de alcance para explicar esto. ¿Pero cómo?

En realidad, estoy trabajando en un proyecto de curso de compilación que requiere que implementemos una versión simplificada del compilador de C. Estaba tratando de lidiar con este caso pero me confundí.

EDITAR: Sé que es de conocimiento común que C está orientado a procedimientos y requiere que los nombres de funciones sean únicos. Pero este estilo local de declaración suscita una situación clara, y es difícil para mí entender su principio / regla.