Wann initialisiert GCC die Variablen?

Gast #1117338
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
Gast #1117355
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
#1117367
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.
#1117408
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.
#1117418
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.
Moderator Persönliche Seite #1117436
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.
#1117442
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.
#1117700
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....
#1117710
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.
#1117711
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).

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren