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.
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).