Forum: Compiler & IDEs Wann initialisiert GCC die Variablen?


von Sebastian (Gast)


Lesenswert?

Hi,

eine kurze Frage zu GCC: Ich definieren außerhalb aller Schleifen ganz 
am Anfang des Programms eine Variable, z.B.:

unsigned int ABC = 0;

Der Compilter initilisiert ABC mit 0 also wenn die Schaltung Strom 
bekommt. Aber auch nach einem Watchdog-Reset? Oder wann noch?

Vielen Dank schonmal!

Sebastian

von Oliver (Gast)


Lesenswert?

>Aber auch nach einem Watchdog-Reset? Oder wann noch?

Die globalen Variablen werden vor dem Auruf von main() initialisiert. 
Also jedes mal, wenn das Programm von ganz vorne gestartet wird. Nach 
jeder Art von Reset, oder auch einem Sprung auf die Startadresse.

Letzteres passiert beim avr-gcc z.B. bei einem Interrupt ohne ISR.

Oliver

von Johannes M. (johnny-m)


Lesenswert?

Sebastian wrote:
> eine kurze Frage zu GCC: Ich definieren außerhalb aller Schleifen ganz
> am Anfang des Programms eine Variable, z.B.:
Du meinst nicht zufällig eine globale Variable?

Eine globale Variable wird, wie Oliver schon andeutete, jedes Mal bei 
der Ausführung des Startup-Codes vor main initialisiert. Das geschieht 
auch (bei mir bekannten Systemen) nach jedem Reset, prinzipiell 
unabhängig davon, wo der Reset herkam.

Globale Variablen werden auch (im Gegensatz zu lokalen) automatisch zu 0 
initialisiert. Das "= 0" bei der Initialisierung kann man sich also 
schenken.

von Sebastian (Gast)


Lesenswert?

Hi Oliver und Johannes,

vielen Dank für Eure beiden schnellen Antworten und den Tip, "=0" nicht 
schreiben zu müssen, nun ist alles klar! :-)

Sebastian

von (prx) A. K. (prx)


Lesenswert?

Johannes M. wrote:

> Das "= 0" bei der Initialisierung kann man sich also schenken.

Es ist sogar so, dass eine explizite Initialierung mit 0 Platz im Flash 
beansprucht, eine implizite Initialisierung hingegen nicht.

von Johannes M. (johnny-m)


Lesenswert?

A. K. wrote:
> Es ist sogar so, dass eine explizite Initialierung mit 0 Platz im Flash
> beansprucht, eine implizite Initialisierung hingegen nicht.
Meinste nicht, dass da die Optimierung zuschlägt? Oder darf die das 
nicht?

von (prx) A. K. (prx)


Lesenswert?

Dürfen tut er schon, denn der C Standard kennt keine bss und data 
sections. Ausprobiert: V2.9 (AIX) optimiert nicht, V4.1 (Linux) 
optimiert.

Vor ein paar Wochen geisterte hier ein kommerzieller Compiler-Output 
durch's Forum, der eine statische Initialisierung sogar individuell per 
Laufzeit-Code vornahm.

von Bernhard M. (boregard)


Lesenswert?

A. K. wrote:
> Dürfen tut er schon, denn der C Standard kennt keine bss und data
> sections. Ausprobiert: V2.9 (AIX) optimiert nicht, V4.1 (Linux)
> optimiert.
>
> Vor ein paar Wochen geisterte hier ein kommerzieller Compiler-Output
> durch's Forum, der eine statische Initialisierung sogar individuell per
> Laufzeit-Code vornahm.

C-Compiler können / sollen eigentlich bei ausgeschalteter Optimierung 
den Speicher / Variablen mit 0 initialisieren, bei eingeschalteter 
Optimierung nicht. Das dürfte den Unterschied von AIX und Linux hier 
erklären.
Bei C-Compiler für Mikrocontroller sieht das u.U. anders aus, da hier 
ganz anderer Initialisierungscode (immerhin das Starten nach dem 
Reset...) eingebaut wird.

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


Lesenswert?

A. K. wrote:

>> Das "= 0" bei der Initialisierung kann man sich also schenken.
>
> Es ist sogar so, dass eine explizite Initialierung mit 0 Platz im Flash
> beansprucht, eine implizite Initialisierung hingegen nicht.

Seit GCC 4.x ist das nicht mehr so, da erkennt der Compiler eine
Initialisierung mit 0 automatisch und sortiert die entsprechende
Variable dann trotzdem ins bss statt nach data.  Früher war es aber
in der Tat so.

Es bringt auch in keinem Falle ,,mehr Sicherheit'', wenn man die
Initialisierung auf 0 mit hinschreibt: wenn ein Laufzeitsystem so
vergurkt ist, dass es die default-Initialisierung auf 0 (die vom
Standard so vorgeschrieben ist) nicht macht, eine explizit
aufgeschriebene Initialiserung jedoch dann trotzdem noch ausführt,
dann weiß ich nicht, wie weit man einem derartigen System überhaupt
übern Weg trauen sollte.

von (prx) A. K. (prx)


Lesenswert?

@Bernhard:

Initialisiert werden müssen die Dinger, ob mit oder ohne Optimierung. 
Die Frage ist eher wie das geschieht. Ob das der Loader erledigt (mit 
Betriebssystem) oder der Startup-Code (ohne BS).

Der gcc 2.9 optimiert die 0 nie weg, egal mit welchem -Olevel. Der gcc 
4.1 wiederum optimiert 0 immer weg, egal mit welchem -Olevel.

Üblicherweise erzeugt ein Compiler für Microcontroller eine 
Flash-Section mit den initialisierten Daten, die im Startup ins RAM 
kopiert wird. Der erwähnte kommerzielle Compiler allerdings hat für jede 
Variable einzeln Code der Art [load register with 1, store register to 
RAM] erzeugt und diesen Code als Initialisierungsektion verwendet. 
Allenfalls bei Arrays mag das nützlich sein.

von Bernhard M. (boregard)


Lesenswert?

Ich habe speziell auf den Linux / AIX Vergleichbezogen.
Zumindest unter Unix ist es üblich, bei angeschaltetem Optimizer NICHT 
zu initialisieren (Performance); es ist in C/C++ Aufgabe des 
Programmierers sich darum zu kümmern, daß Variablen richtig initialisert 
werden.

Daß der Compiler (speziell für Microcontroller) da dann den besten Code 
erzeugen soll (und evtl. sogar die initialisierung wegoptimiert, weil er 
ja weiß, daß die Laufzeitumgebung sowieso mit 0 vorlöscht) ist etwas 
anderes....

von Stefan E. (sternst)


Lesenswert?

Bernhard M. wrote:

> Zumindest unter Unix ist es üblich, bei angeschaltetem Optimizer NICHT
> zu initialisieren (Performance);

Das stimmt für globale (und auch statische lokale) Variablen einfach 
nicht. Die Initialisierung dieser mit 0 ist Bestandteil der Sprache, und 
darf nicht weggelassen werden.

von (prx) A. K. (prx)


Lesenswert?

Bernhard M. wrote:

> Zumindest unter Unix ist es üblich, bei angeschaltetem Optimizer NICHT
> zu initialisieren (Performance); es ist in C/C++ Aufgabe des
> Programmierers sich darum zu kümmern, daß Variablen richtig initialisert
> werden.

Nein. C- und C++-Standards definieren, dass statische und globale 
Variablen vor Ausführung von main() von Loader oder Startup-Code 
initialisiert werden. Wenn nicht anders angegeben, dann auf 0. Egal ob C 
oder C++ und egal ob mit Optimierung oder ohne. Egal ob Unix, Windows 
oder MacOS.

Anders liegt der Fall bei lokalen Variablen mit storage class auto oder 
register. Aber um die ging es in diesem Kontext nicht (mehr).

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.