Wie viele Codezeilen enthält das folgende Programm?
#include <iostream>
int main()
{
std::cout << "Hello, world!\n";
return 0;
}
Sie haben wahrscheinlich mit 7 geantwortet (oder mit 6, wenn Sie die leere Zeile nicht gezählt haben, oder mit 4, wenn Sie die geschweiften Klammern nicht gezählt haben).
Ihr Compiler sieht jedoch etwas ganz anderes:
~$ cpp hello.cpp | wc
18736 40822 437015
Ja, das sind 18,7 KLOC nur für eine "Hallo Welt!" Programm. Der C ++ - Compiler muss das alles analysieren . Dies ist ein Hauptgrund, warum die C ++ - Kompilierung im Vergleich zu anderen Sprachen so lange dauert und warum moderne Sprachen Header-Dateien meiden.
Eine bessere Frage wäre
Warum hat C ++ Header-Dateien?
C ++ wurde als Obermenge von C entwickelt, daher mussten Header-Dateien aus Gründen der Abwärtskompatibilität aufbewahrt werden.
OK, warum hat C Header-Dateien?
Wegen seines primitiven separaten Kompilierungsmodells. Die von C-Compilern generierten Objektdateien enthalten keine Typinformationen. Um Typfehler zu vermeiden, müssen Sie diese Informationen in Ihren Quellcode aufnehmen.
~$ cat sqrtdemo.c
int main(void)
{
/* implicit declaration int sqrt(int) */
double sqrt2 = sqrt(2);
printf("%f\n", sqrt2);
return 0;
}
~$ gcc -Wall -ansi -lm -Dsqrt= sqrtdemo.c
sqrtdemo.c: In function ‘main’:
sqrtdemo.c:5:5: warning: implicit declaration of function ‘printf’ [-Wimplicit-function-declaration]
sqrtdemo.c:5:5: warning: incompatible implicit declaration of built-in function ‘printf’ [enabled by default]
~$ ./a.out
2.000000
Das Hinzufügen der richtigen Typdeklarationen behebt den Fehler:
~$ cat sqrtdemo.c
#undef printf
#undef sqrt
int printf(const char*, ...);
double sqrt(double);
int main(void)
{
double sqrt2 = sqrt(2);
printf("%f\n", sqrt2);
return 0;
}
~$ gcc -Wall -ansi -lm sqrtdemo.c
~$ ./a.out
1.414214
Beachten Sie, dass es keine #include
s gibt. Wenn Sie jedoch eine große Anzahl externer Funktionen verwenden (was die meisten Programme tun), wird das manuelle Deklarieren dieser Funktionen mühsam und fehleranfällig. Es ist viel einfacher, Header-Dateien zu verwenden.
Wie können moderne Sprachen Header-Dateien vermeiden?
Durch Verwendung eines anderen Objektdateiformats, das Typinformationen enthält. Das Java * .class-Dateiformat enthält beispielsweise "Deskriptoren", die die Feldtypen und Methodenparameter angeben.
Dies war keine neue Erfindung. Früher (1987), als Borland Turbo Pascal 4.0 separat kompilierte "Einheiten" hinzufügte, entschied es sich, ein neues *.TPU
Format anstelle von Turbo C zu *.OBJ
verwenden, um die Notwendigkeit von Header-Dateien zu beseitigen.