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:
1
main()
2
{
3
while(1)
4
{
5
6
if(...)
7
{
8
if(...)
9
{
10
}
11
else
12
{
13
if(...)
14
{
15
switch()
16
{
17
// 6 case-Fälle
18
}
19
20
if(....)
21
{
22
switch(...)
23
{
24
// 5 case-Fälle
25
}
26
}
27
}
28
}
29
flag_jbusmsg_ok=TRUE;
30
DebugLed2Off;
31
}// while(1);
32
33
return0;
34
}
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?
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;
...
Es wird auf TRUE und an anderer Stelle auf FALSE gesetzt, es wird auch
per if(...) abgefragt.
1
while(1)
2
{
3
...
4
if(....)
5
{
6
...
7
if(data1==146)
8
{
9
flag_jbusmsg_ok=TRUE;
10
...
11
}
12
else
13
{
14
flag_jbusmsg_ok=FALSE;
15
...
16
}
17
}
18
else
19
{
20
if(flag_jbusmsg_ok==TRUE)
21
{
22
....
23
}
24
}
25
flag_jbusmsg_ok=TRUE;
26
DebugLed2Off;
27
}
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?
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.
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?
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? ;-)
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.
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.