Nie jestem projektantem kompilatora, ale obserwując efekty jego działania (tak, tak - błędy to są też efekty! ;) sądzę, że napotykając na deklarację funkcji, zapisuje ją sobie w jakimś miejscu przeznaczonym do tego celu, z ewentualnym pustym polem na adres (czy może raczej: offset?), do wypełnienia "później".
Jeśli piszesz program w IDE, to dodajesz pliki do projektu źródłowe (z definicjami), prawda?
Jeśli kompilator natrafia na definicję (w Twoim pliku), to do wcześniej przygotowanej deklaracji może dorzucić adres ciała funkcji.
Jeśli takiej definicji w Twoich plikach nie znajdzie, to po prostu zostawi pole adresu puste, obarczając Ciebie zadaniem dostarczenia linkerowi (który pracuje po kompilatorze) odpowiednich skompilowanych plików.
A jeśli linker takich nie dostanie, to Ty dostaniesz... komunikat linkera: "undefined reference to...". :)
Oczywiście to tylko moje domysły. :)