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
>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
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.
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
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.
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?
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.
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.
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.
@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.
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....
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.