Forum: Compiler & IDEs Optimierung scheint zu gut (Code wird nicht ausgeführt)


von Alex1 (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich habe mal wieder eine OptimierungsSache:

tInt8 ReadBatteryStatus (void)
  {
    tIntU8 Data [3];
    nLastBatteryStatus = SW_UNKNOWN_ERROR;
    Data [0] = BATTERY_STATUS;
    tInt8 Ret = TWI_ReadWord (TWI_SLA_ADDR, Data, 1);
    if (Ret == TWI_NO_ERROR)
      {
        nLastBatteryStatus  = Data [1];
        nLastBatteryStatus |= Data [2] << 8;
      }
    return ((tInt8)Ret);
  }

tSMBusResult BatteryStatusOk (void)
  {
    tInt8 Ret = ReadBatteryStatus ();
//+++++++++++++++++++++++++++++++++
    if (Ret == ((tInt8)TWI_NO_ERROR))
      {
        if (chk_bit (nLastBatteryStatus, SW_OK) != 0)
          return idSMBusResOk;
      }
//+++++++++++++++++++++++++++++++++
    return idSMBusResErr;
  }

Der Code zw. den //++++ wird nir aufgerufen. Habe jetzt schon alle 
optimierungsvarianten durch.

Ich haenge mal das lls dran.
Da ich in asm nur ein gefährliches Halbwissen habe, könnte ich jetzt nur 
mit 50%tigen Sicherheit sagen, dass der Code wegoptimiert wird.
Aber warum?

Danke
Alex

von Andreas K. (a-k)


Lesenswert?

Was genau ist chk_bit? Kann es sein, dass diese Funktion / dieser Macro 
mit diesen Parametern grundsätzlich nur 0 liefert?

von Alex1 (Gast)


Lesenswert?

Ja, chk_bit ist ein Makro:
#define chk_bit(x,y) (x & (y))   // Check bit y in byte x

Alex

von Martin (Gast)


Lesenswert?

Hallo,

vielleicht ist SW_OK = 0 und es war eigentlich die Bitnummer 0 gemeint.
Dann sollte das Makro aber so aussehen:

#define chk_bit(x,y) (x & (1 << y))   // Check bit y in byte x

Gruß,
Martin

von Stefan (Gast)


Lesenswert?

Wird denn
1
tInt8 ReadBatteryStatus (void)
2
  {
3
   ...
4
   if (Ret == TWI_NO_ERROR)
5
      {
6
       ...
7
      }
8
   ...
9
  }
jemals aufgerufen?

Ich meine, wenn Ret niemals TWI_NO_ERROR ist, dann wird in Deine 
Abfrage logischerweise auch nie verzweigt.

Was mir noch auffällt:
In ReadBatteryStatus() vergleichst Du
1
if (Ret == TWI_NO_ERROR)

In BatteryStatusOk() castest Du
1
if (Ret == ((tInt8)TWI_NO_ERROR))

Kann da der Hund begraben liegen?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Was sagen denn die Compilerwarnungen bei -Wall -Wextra so?

von OliverSo (Gast)


Lesenswert?

>Optimierung scheint zu gut (Code wird nicht ausgeführt)

An der Optimierung liegt es nicht, und der Code wird auch nicht 
wegoptimiert. Wenn er nicht ausgeführt wird, kanns nur daran liegen, daß
1
if (Ret == ((tInt8)TWI_NO_ERROR))
 nicht erfüllt wird.
Das aber liegt nicht in der Gewalt des Compilers :-)

Was ist denn ein tInt8? Gefallen dir die vordefinierten Typen aus 
stdint.h nicht?

Oliver

von Andreas K. (a-k)


Lesenswert?

Stefan wrote:

> if (Ret == ((tInt8)TWI_NO_ERROR))
>
> Kann da der Hund begraben liegen?

Nein. Denn Ret ist vom Typ tInt8 und (tInt8)TWI_NO_ERROR liegt folglich 
in dessen Wertebereich. Und daher kann dieses Statement zwar inhaltlich 
Blödsinn sein, der Compiler darf es aber nicht ignorieren.

von Andreas K. (a-k)


Lesenswert?

Es fehlt immer noch die Definition von SW_OK.

von Stefan (Gast)


Lesenswert?

Andreas Kaiser wrote:
>Denn Ret ist vom Typ tInt8 und (tInt8)TWI_NO_ERROR liegt folglich
>in dessen Wertebereich.
Prinzipiell schon, aber TWI_NO_ERROR muss nicht vom Typ tInt8 sein, 
weshalb ja gecastet wird.
Möglicherweise (Fälschlicherweise) interpretiert der Compiler einen 
Vergleich
1
Ret == TWI_NO_ERROR
anders als
1
Ret == (tInt8)TWI_NO_ERROR
?!

von OliverSo (Gast)


Lesenswert?

Da ReadBatteryStatus (); den Wert schon als tInt8 zurückgibt, kann es 
daran nicht liegen.

Aber egal, da hilft nur debuggen. uart-ausgaben einbauen, LED'S an 
freien Ports an- und auschalten, VMLAB-Modell bauen, JTAG, was auch 
immer.

Da muß jeder irgendwann  mal durch.

Olvier

von Andreas K. (a-k)


Lesenswert?

Wir sollten warten bis der Fragesteller Antwort auf die SW_OK Frage 
gibt, das halte ich nämlich für die wahrscheinlichste Ursache. 
Vielleicht hat er das ja auch schon gemerkt und sich längst ausgeklinkt.

von Karl H. (kbuchegg)


Lesenswert?

Andreas Kaiser wrote:
> Es fehlt immer noch die Definition von SW_OK.

Ja. Die wäre interessant.
Wenn da steht

#define SW_OK  0

dann wäre das alles erklärbar.
So gross scheint das Programm ja nicht zu sein.
Poste mal alles. Ansonsten ist das ein Stochern im Nebel.

Die Wahrscheinlichkeit dass du einen Programmfehler hast
ist um einige Zehnerpotenzen größer, als das du einen Fehler
im Compiler entdeckt hast.

von OliverSo (Gast)


Lesenswert?

Nachtrag:
1
tInt8 Ret = TWI_ReadWord (TWI_SLA_ADDR, Data, 1);

Ist denn sicher, daß die TWI-Kommunikation überhaupt funktioniert? Wenn 
da immer TWI_ERROR zurückkommt, braucht man weiter unten nicht mehr zu 
suchen.

Oliver

von Detlev T. (detlevt)


Lesenswert?

SW_OK ist 0. Das ergibt sich aus dem Listing
1
    tIntU16 nBatteryStatus = SW_OK;
2
      d0:  1a 82         std  Y+2, r1  ; 0x02
3
      d2:  19 82         std  Y+1, r1  ; 0x01

r1 ist bei GCC immer 0, wenn ich mich nicht irre.

von Andreas K. (a-k)


Lesenswert?

Na dann... case closed. Alex1 hätte sich freilich noch mal melden 
können.

von Alex1 (Gast)


Lesenswert?

Hallo zusammen,

das ist ja ein Ding!!! So viele Rückmeldungengen in so kurzer Zeit...

Es war das makro (war immer false).

Danke

Alex

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
Noch kein Account? Hier anmelden.