Forum: Compiler & IDEs Deklaration/Definition globaler Variablen


von Walter T. (nicolas)


Lesenswert?

Hallo zusammen,
ich habe in einer wachen Minute heute Nacht festgestellt, daß ich nicht 
verstanden habe, wie der Linker arbeitet. Ich habe in einem Projekt in 
unterschiedlichen c-Dateien globale Variablen mit dem gleichen Namen 
aber unterschiedlichen Größen deklariert, also z.B.
1
//Datei1.c:
2
uint8_t gl_buffer[100];
3
4
...
5
6
//Datei2.c:
7
uint8_t gl_buffer[64];
8
9
...
10
11
//Datei 3.c:
12
uint8_t gl_buffer[1024];
(Das war keine Absicht, sondern ist meiner Phantasielosigkeit bei der 
Namensgebung geschuldet.)
Initialisiert werden die Arrays nie, sondern nur bei Bedarf gefüllt. Und 
offensichtlich steht der große Puffer auch zur Verfügung, ansonsten 
wären die Auswirkungen eines Speicherüberlaufs (hoffentlich) schon zu 
merken gewesen. Und die Arrays werden auch nicht stillschweigend zu 
"static" erklärt, sonst wäre die Gesamtgröße größer als der SRAM.

Aber was macht der Linker an dieser Stelle?

Viele Grüße
W.T.

von Dr. Sommer (Gast)


Lesenswert?

Walter Tarpan schrieb:
> Initialisiert werden die Arrays nie, sondern nur bei Bedarf gefüllt.
Doch, globale Variablen werden zu 0 initialisiert.

Walter Tarpan schrieb:
> Aber was macht der Linker an dieser Stelle?
Meckern, dass mehrere C-Dateien das selbe Linker-Symbol "gl_buffer" 
definieren.

von Walter T. (nicolas)


Lesenswert?

Hoppla....ich habe gerade gesehen, daß die Variablen doch alle "static" 
sind. Aber jetzt wundere ich mich um so mehr. Die Gesamtgröße dürfte 
nicht ins SRAM passen...

Und in der Überschrift würde ich gerne noch ein "t" spendieren.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Was sagt denn sie statische Speicherbelegung, etwa mit size? 
Linkerskripte sind i.d.R nicht Device-spezifisch sondern nur 
Core-Spezifisch, d.h. der Linker weiß nicht, wie viel RAM wirklich 
vorhanden ist, d.h. er meckert nur bei krasser Uberschreitung der Größe.

Falls die Variablen nicht static sind, hängt das Verhalten von 
-f[no-]common an. IdR ist -fcommon Standard, d.h. die Variablen werden 
"üebreinander" gelegt.  Mit -fno-common würde der Linker meckern weil 
die Symbole unterschiedliche Größe haben.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Walter Tarpan schrieb:
> Und in der Überschrift würde ich gerne noch ein "t" spendieren.

Erledigt.

Johann L. schrieb:
> IdR ist -fcommon Standard, d.h. die Variablen werden "üebreinander"
> gelegt.

Da es für COMMON-Blöcke in FORTRAN durchaus nicht unüblich war, dass
sie unterschiedliche Größe besitzen, erklärt das auch, warum der Linker
in diesem Falle nicht meckert.  Er legt das Symbol dann einfach mit
der größten geforderten Größe an, die anderen Module können dann den
Anfang davon zugreifen.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Johann L. schrieb:
> IdR ist -fcommon Standard, d.h. die Variablen werden
> "üebreinander" gelegt.

Das mag "standard" sein, ist aber gerade für Programmieranfänger eine 
sehr schöne Fehlerquelle.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Rufus Τ. Firefly schrieb:

> Das mag "standard" sein, ist aber gerade für Programmieranfänger eine
> sehr schöne Fehlerquelle.

Ja, „Standard“ ist es auch (im Sinne von „kompatibel mit dem
C-Standard“), aber Johann wollte wohl damit eher ausdrücken, dass es
beim GCC “default” ist, also die Voreinstellung, sofern es nicht durch
-fno-common überschrieben worden ist.  Auch das Verhalten gemäß
-fno-common ist kompatibel mit dem C-Standard, er gestattet explizit
beides.

Keine Ahnung, warum das beim GCC die übliche Voreinstellung ist,
vermutlich: „Das haben wir schon immer so gemacht.“  ;-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.