Warum main () kann nicht als statisch in C deklariert werden?
Frage
Warum Haupt müssen deklariert werden, als ob es eine externe Bindung hat?
Warum soll es nicht statisch sein?
, was durch externe Bindung gemeint ??
Lösung
Weil Sie verknüpfen die Startdateien auf Ihrem Programm, das enthält (in der Regel) Assembler-Code, der Ihre Haupt aufruft. Wenn Haupt statisch wäre, würde dieser Code nicht in der Lage sein Haupt nennen.
external linkage
bedeutet, dass andere so genannte translation-units
Ihr Symbol erklärt extern in einer eigenen Übersetzung-Einheit sehen. Also, Ihr Haupt ist extern, und es wird einen Eintrag in seiner Übersetzung Einheiten Symboltabelle hat, die seine Adresse angibt. Weitere Übersetzungseinheiten werden dann in der Lage sein, an diese Adresse zu springen, wenn sie Haupt anrufen möchten.
static linkage
bedeutet, dass Ihr Symbol streng übersetzungsEinheit lokal ist. Das bedeutet, andere translation units
nicht in der Lage sein, dieses Symbol zu sehen. Somit Symbole mit statischer Verknüpfung in verschiedenen Übersetzungseinheiten mehrfach auftreten können, und sie werden nicht miteinander kollidieren, weil sie lokal sind.
Bearbeiten : Im Allgemeinen Dateien vom Compiler von Übersetzungseinheiten erzeugt sind spezifisch für diesen bestimmten Compiler. Für gcc unter Linux, oft wird das ELF Objektformat verwendet.
: Sie können ihre Symboltabelle mitreadelf -sW <file>.o
(einfache Test-Datei unten) anzuzeigen
test.c
void bar(void);
static int foo(void) {
return 1;
}
int main(void) {
bar();
return foo();
}
Hier ist die Ausgabe von readelf:
Symbol table '.symtab' contains 10 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 FILE LOCAL DEFAULT ABS test.c
2: 00000000 0 SECTION LOCAL DEFAULT 1
3: 00000000 0 SECTION LOCAL DEFAULT 3
4: 00000000 0 SECTION LOCAL DEFAULT 4
5: 00000000 10 FUNC LOCAL DEFAULT 1 foo
6: 00000000 0 SECTION LOCAL DEFAULT 6
7: 00000000 0 SECTION LOCAL DEFAULT 5
8: 0000000a 36 FUNC GLOBAL DEFAULT 1 main
9: 00000000 0 NOTYPE GLOBAL DEFAULT UND bar
Sie sehen die Hauptfunktion, und eine statische foo Funktion, durch das Haupt genannt. Auch gibt es eine Funktion aufgerufen, die nicht in der Datei definiert ist, die aber in einer anderen Objekt-Datei definiert. Da die Objektdatei noch nicht endgültig verbunden war, haben die Funktionen nicht Endadressen noch zugeordnet. Nach dem Endglied, werden diese in die ausführbaren angeordnet werden und Adressen zugeordnet haben. Die Objektdatei enthält Einträge für Anrufe noch nicht definierten Funktionen, so dass, wenn die Datei verknüpft ist, können diese Aufruf-Instruktionen die letzten Adressen gespeichert (readelf -r <file>.o
):
Relocation section '.rel.text' at offset 0x308 contains 1 entries:
Offset Info Type Sym.Value Sym. Name
0000001c 00000902 R_386_PC32 00000000 bar
Andere Tipps
Der eigentliche Ausgangspunkt des Codes ist in der C-Laufzeitbibliothek begraben. Diese Laufzeitbibliothek ruft Ihre main () Routine. Damit der Linker den C RTL Anruf mit Ihrem main () Funktion zu verbinden, muss es außerhalb der Datei sichtbar sein.
Externe Verknüpfung ist nur dies: es bedeutet, dass der betreffende Name als Teil der Ausfuhren der Objektdatei sichtbar ist. Der Auftrag des Linkers ist, alle Einfuhren zu verbinden und die Exporte, so dass es keine ausstehenden Einfuhren sind.