Werden statische lokale Arrays vom XC32 compiler automatisch beim Programmstart auf 0 initialisiert

OP #8094488
Lesenswert?

Hallo, wird bei dem XC32 Compiler von Microchip das u.g. lokale statische Array "static int Puffer[MaxNummer][MaxWerte];" bei Prozessorstart automatisch auf 0 initialisiert ?

1
int Ringpuffer (int Messwert,int Nummer)
2
    {
3
    #define MaxNummer   12  // Maximale Anzahl an Filtern 
4
    #define MaxWerte    5  // Maximale Anzahl an Pufferwerten pro Filter
5
    static int Puffer[MaxNummer][MaxWerte];
6
    static int Zeiger[MaxNummer]; // Nummer 0... des aktuellen Messwertes der geschrieben wird
7
    int Ergebnis,Schleife;
8

9
// Der Rest code kommt später
#8094491
Lesenswert?

Normalerweise schon (Liegen im BSS). Aber schreib einfach

1
static int Puffer[MaxNummer][MaxWerte] = {0};
2
static int Zeiger[MaxNummer] = {0};

Wenn dir die Initialisierung wichtig ist.

Wenn der Compiler das eh gemacht hätte, ist das kein zusätzlicher Code, und es dient gleichzeitig als Kommentar.

: Bearbeitet durch User
Moderator Persönliche Seite #8094496
Lesenswert?

Dirk F. schrieb:

Hallo, wird bei dem XC32 Compiler von Microchip das u.g. lokale statische Array "static int Puffer[MaxNummer][MaxWerte];" bei Prozessorstart automatisch auf 0 initialisiert ?

Wenn er mit dem C-Standard konform ist: ja.

Εrnst B. schrieb:

Wenn der Compiler das eh gemacht hätte, ist das kein zusätzlicher Code

Kann man nicht garantieren. Der GCC hatte dafür vor Jahren explizit zusätzlichen Code produziert.

#8094528
Lesenswert?

bei den alten PIC-Compilern (bevor sie non Microchip aufgekauft wurden) musste man den Startup-Code entsprechend ... konfigurieren/anpassen. Oft zählt da halt Zeit/platz

Normalerweise trennt ein Compiler zwischen Bereichen, die gelöscht werden und Bereiche, die initialisiert werden.

Über den gelöschten Bereich wird einfach jedes Byte mit 0 beschrieben, der initialisierte hat ein pendant im Flash, das drüberkopiert wird.

Such mal unter Startup im Handbuch. Alternative (nicht ganz so sicher): Initialisiere mit einem Feld ungleich 0 und schaue, ob der Code (genauer: Der ROM-Bedarf) mehr wird. Im anderen Schritt lasse die Initialisierung ganz weg und schaue im Linker-File, ob es eine andere "section" gibt, in der die Variable jetzt liegt

: Bearbeitet durch User
OP #8095594
Lesenswert?

Hallo, habe es mal getestet.

1
        //  ----Bytes used-------
2
        //  Data used / Prog used
3
        //  107.318   / 344.182  Array auskommentiert
4
        //  113.718   / 344.226  mit Array ohne Initialisierung
5
        //  113.718   / 344.226  mit Array mit Initialisierung 0      
6
        //  113.718   / 344.274  mit Array mit Initialisierung 11
7
        
8
        static int Puffer[16][100]={11};
9
        Puffer[1][1]++;

Wenn ich also das Array mit 0 initialisiere, hat es den gleichen Speicherverbrauch wie ohne Initialisierung. Danke für den Tipp.

Was ich nicht verstehe: Warum werden bei Initialisierung mit "11" nur 48 Byte mehr Flash verbraucht, obwohl das Feld ja 100 * 16 * 4 Byte groß ist.

: Bearbeitet durch User
Moderator Persönliche Seite #8095649
Lesenswert?

Dirk F. schrieb:

Warum werden bei Initialisierung mit "11" nur 48 Byte mehr Flash verbraucht, obwohl das Feld ja 100 * 16 * 4 Byte groß ist.

Die Frage wäre korrekt: warum werden überhaupt 48 Byte verbraucht? Vermutlich wird in dem Moment der Initialisierungscode erst mit gelinkt – aber das müsstest du an deinem Compilat selbst erkunden.

Dass du nur das erste Byte auf 11 initialisierst und den Rest auf 0, wird dir spätestens dabei auch auffallen. ;-)

#8095677
Lesenswert?

Jörg W. schrieb:

warum werden überhaupt 48 Byte verbraucht?

Vermute es war die einzige initialisierte Variable im Code, und der entsprechende INIT-Code-Block wird sonst garnicht eingebaut?

aus der pic32 "crt0.S":

1
#if defined(INIT_DATA) || defined(__PIC32_HAS_INIT_DATA)
2
        ##################################################################
3
        # Initialize data using the linker-generated .dinit table
4
        ##################################################################
5
...
#8095685
Lesenswert?

Dirk F. schrieb:

Wenn ich also das Array mit 0 initialisiere, hat es den gleichen Speicherverbrauch wie ohne Initialisierung.

Weil es in beiden Fällen identisch initialisiert wird, wenn das System C-konform aufgesetzt ist.

Was ich nicht verstehe: Warum werden bei Initialisierung mit "11" nur 48 Byte mehr Flash verbraucht, obwohl das Feld ja 100 * 16 * 4 Byte groß ist.

Es ist durchaus plausibel, dass die Compiler-Hersteller auch diesen Speicherverbrauch optimieren: Während es früher bei den von mir genutzten Compilern schwarz/weiß-Entscheidungen waren (nichts initialisiert vs. mindestens 1 Feld), ist es eine sehr sinnvolle Verbesserung, das Array in die "gelöschte"-Sektion zu packen und danach explizit das eine Feld auf 11 zu setzen.

#8095691
Lesenswert?

Dirk F. schrieb:

Ist das wirklich so ? Das würde den zweiten Beitrag von Ernst B. wiedersprechen.

Wenn eine Initialisierungsliste kürzer ist als die Gesamtzahl der Elemente im Array, werden alle nicht explizit erwähnten Elemente standardmäßig mit dem Nullwert des jeweiligen Datentyps (bei int also 0) initialisiert.

d.H. ein Element auf 11, der Rest auf 0.

Moderator Persönliche Seite #8095732
Lesenswert?

Εrnst B. schrieb:

Wenn eine Initialisierungsliste kürzer ist als die Gesamtzahl der Elemente im Array, werden alle nicht explizit erwähnten Elemente standardmäßig mit dem Nullwert des jeweiligen Datentyps (bei int also 0) initialisiert.

Das trifft übrigens für alle Initialisierungen zu, nicht nur bei statischer Speicherklasse. Also auch wenn obige Variable von der Speicherklasse "auto" wäre, würde sie durch benennen eines einzigen (in diesem Falle auch eines von 0 verschiedenen) Initialwertes im Rest der Variable genullt.

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