mikrocontroller.net

Forum: Compiler & IDEs -554 Byte = 1 Befehl?


Autor: Hegy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe gerade festgestellt, daß mein Binärcode um 554 Byte größer(!) 
wird, wenn ich einen Befehl weglasse(!) bzw. einen anderen konstanten 
Wert zuweise. Ich vermute mal, daß da die Optimierung des GCC nicht mehr 
kann, wenn der eine Befehl fehlt.

Zusammengefaßt sieht es so aus:
main()
{
  while(1)
  {

  if(...)
  {
    if(...)
    {
    }
    else
    {
      if(...)
      {
        switch()
        {
          // 6 case-Fälle
        }

        if(....)
        {
          switch(...)
          {
            // 5 case-Fälle
          }
        }
      }
    }
    flag_jbusmsg_ok = TRUE;
    DebugLed2Off;
  } // while(1);

  return 0;
}

So sieht das im groben aus.
Wenn ich flag_jbusmsg_ok (Typ uchar8) auf FALSE (=0) setzte oder den 
Befehl DebugLed2Off (= PORTA &= ~0x04) weglasse (fünft- und sechstletzte 
Zeile) oder auch beide Befehle weglasse, wird das Binärfile im Flash 
über ca. 550 Byte größer. Der Befehl "flag_jbusmsg_ok = TRUE" soll 
nämlich raus und das Proggi natürlich klein bleiben. Es würde übrigens 
von derzeit 4626 Byte auf 5180 Byte anwachsen.


Wie kann ich sowas umgehen, wenn ich den Code klein halten will?

Autor: Frank B_. (frank_b) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schau mal, wo flag_jbusmsg_ok überall verwendet wird.

Wenn es ohne diese Zeile oben nie auf true gesetzt wird, kann es gut 
sein, dass der Optimierer alle diezbezüglichen Programmteile ersatzlos 
streicht, weil es ja nie true wird...

ich meine sowas:
if (flag_jbusmsg_ok) {
 blah;
...

Autor: Frank B_. (frank_b) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
bzw umgekehrt :-)

Autor: Hegy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es wird auf TRUE und an anderer Stelle auf FALSE gesetzt, es wird auch 
per if(...) abgefragt.
while(1)
{
  ...
  if(....)
  {
    ...
    if(data1 == 146)
    {
      flag_jbusmsg_ok = TRUE;
      ...
    }
    else
    {
      flag_jbusmsg_ok = FALSE;
      ...
    }
  }
  else
  {
    if(flag_jbusmsg_ok == TRUE)
    {
      ....
    }
  }
  flag_jbusmsg_ok = TRUE;
  DebugLed2Off;
}

Es ist ja nicht nur die Var., die da evtl. über wäre, das würde der GCC 
ja auch anmerkeln (warning: flag_jbusmsg_ok defined but not used), schon 
der Wert der Var., der zugewiesen wird, macht einen Riesenunterschied. 
Und auch, wenn ich den 2. Befehl darunter weglasse (DebugLed2Off), bläst 
sich das Programm auf, obwohl DebugLed2Off nur 1x verwendet wird.

Kann es war mit Sprungweite zu tun haben?

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schau dir den erzeugten Assembelercode an, dann wirst du wissen, wo
die 554 Bytes herkommen.

Oder poste mal ein kompilierbares Programmmodul, anhand dessen man das
Problem nachvollziehen kann.

Autor: Hegy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vermutlich daher, daß eine if-Abfrage immer false ist und damit über 
ist und rausoptimiert wird. Wenn das so ist, dann wäre es hilfreich eine 
entsprechende Warnung vom GCC zu bekommen. So sucht man Fehler und 
findet sie nicht. Hätte ich eine Warnung wie bei nicht genutzten 
Variablen bekommen, würde man sich vor dem flashen schonmal nen Kopp 
machen und sich sicher sein, daß das Proggi nicht funzt.

Vermutung deswegen, weil ich die ganzen Krams mit der Variable und 
if-Abfrage komplett gekickt habe und dennoch wird der Code nicht mehr so 
klein (4626 Byte), sondern bleibt bei ca. 5100 Byte.

Meinst du wirklich jemand zieht sich den ganzen Code rein und kukkt sich 
das mal ernsthaft an?

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

Bewertung
0 lesenswert
nicht lesenswert
Hegy wrote:

> Wenn das so ist, dann wäre es hilfreich eine
> entsprechende Warnung vom GCC zu bekommen.

Bekommst du auch, wenn du die entsprechenden Optionen (-Wall -Wextra)
aktivierst.  Aber wer guckt sich schon Warnungen an? ;-)

Autor: Hegy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe "mal eben schnell" nachgekukkt, was man an Optionen einstellen muß, 
damit die Warnungen über nicht erreichbaren Code kommen. Dazu muß die 
Option  -Wunreachable-code mit rein. Es wird immer eine Warnung geben in 
der main()-Fkt., weil diese ja immer mit return x; abschließt aber 
niemals aus einer while(1)-Schliefe erreicht wird.

Bzgl. meines Problems habe ich damit festgestellt, daß ein etwas 
längeres if-Statement nicht durchlaufen wird, wenn die Var. 
flag_jbusmsg_ok = TRUE ist. Wenn ich die Var. dagegen auf FALSE setze, 
besteht die Möglichkeit, daß das if-Statement durchlaufen wird und somit 
werden ca. 30 Zeilen Code mit übersetzt und nicht rausgeschmissen, was 
dann den Unterschied im Binärfile von ca. 550 Byte ausmacht. Damit wäre 
das Problem erklärt.

Also packe ich die Option -Wunreachable-code jetzt immer mit rein, hilft 
ja und Warnungen nehme ich beim GCC durchaus ernst.

Autor: Εrnst B✶ (ernst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hegy wrote:
> ... Option  -Wunreachable-code mit rein. Es wird immer eine Warnung geben in
> der main()-Fkt., weil diese ja immer mit return x; abschließt aber
> niemals aus einer while(1)-Schliefe erreicht wird.

du kannst main mit __attribute__((noreturn)) deklarieren, wenn du da nie 
rauslaufen willst.

Autor: Hegy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie macht man sowas mit der main()-Funktion?

Ich bin wohl nicht der einzige, wo es nicht ohne Warnungen funktioniert.
http://www.mikrocontroller.net/articles/AVR-GCC-Co...

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

Bewertung
0 lesenswert
nicht lesenswert
int main(void) __attribute__((noreturn));
int
main(void)
{
   // ...
}

Wenn du einen aktuell gepatchten Compiler hast, kannst du auch mal
das Attribut OS_main ausprobieren.

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.