www.mikrocontroller.net

Forum: Compiler & IDEs Wann initialisiert GCC die Variablen?


Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Bernhard M. (boregard)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Bernhard M. (boregard)
Datum:

Bewertung
0 lesenswert
nicht 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....

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.