Nehmen wir an, ich habe zwei Quelldateien: main.c
und a.c
:
main.c
: a.c
: Nach dem letzten C99-Entwurf 6.9.2
Externe Objektdefinitionen p. 2 (Betonung meins):
Eine Deklaration eines Bezeichners für ein Objekt mit Dateibereich ohne einen Initialisierer und ohne einen Speicherklassenspezifizierer oder mit Der Speicherklassenbezeichner
static
ist ein Vorbehalt Definition . Wenn eine Übersetzungseinheit eine oder mehrere vorläufige enthält Definitionen für einen Bezeichner, und die Übersetzungseinheit enthält no externe Definition für diese Kennung, dann ist das Verhalten genau als ob die Übersetzungseinheit eine Dateiumfangsdeklaration davon enthält Identifikator, mit dem zusammengesetzten Typ am Ende der Übersetzung Einheit, mit einem Initialisierer gleich 0.
Zusammenstellung (keine Warnungen angegeben):
%Vor% Ich verstehe, dass für i
Variable zwei vorläufige Definitionen sind und da main.c
keine "wahre" externe Definition hat, werden sie in eine solche Definition zusammengeführt. Was ist mit a
? Sage ich richtig, dass vorläufige Definitionen nicht zwischen mehreren Quelldateien (d. H. Übersetzungseinheiten) "geteilt" werden?
Ihr Programm ist fehlerhaft: es definiert denselben externen Namen mehr als einmal. Die GNU-Toolkette folgt einem entspannten Verknüpfungsmodell, das dies nicht als Fehler kennzeichnet; es führt die mehreren Definitionen zusammen. Dies ist jedoch effektiv eine Spracherweiterung. Streng übereinstimmende ISO-C-Programme können einen Namen nicht mehr als einmal definieren.
Der Begriff "vorläufige Definition" ist rein syntaktisch innerhalb einer Übersetzungseinheit. Am Ende einer Übersetzungseinheit werden alle Definitionen, die noch vorläufig sind, als Definitionen "zementiert".
Der Grund, warum int i;
"vorläufig" genannt wird, ist, dass es in gewisser Hinsicht "schwach" ist. Es kann durch eine spätere Definition überschrieben werden. Wenn dies am Ende der Übersetzungseinheit nicht der Fall ist, wird es in int i = 0
umgewandelt.
So ist das zum Beispiel gültig:
%Vor% In dieser Situation wird i
als einmal definiert, nicht als zweimal definiert. Die übersetzte Einheit enthält eine einzige Definition von i.