Forum: Compiler & IDEs Rechen-Zuweisung von Variable in GCC


von G. B. (garyb)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

irgendwie stehe ich auf dem Schlauch - geb gerne zu das mein C 
eingerostet ist, aber warum der WINAVR-GCC die folgende Zeile nicht
ausführt bzw. anscheinend erst gar nicht compiliert - verstehe ich nicht


  TimerCnt += 32/8; //_TIME_CONST_US_TIMER_CLOCK (32); //

Diese Zeile erscheint in keinster Weise im Disassembler-Code.
Beim Debuggen hüpft er drüber und die Variable hat den Wert Null.
Compiler-Option -Os (keine Optimierung ) ist gewählt.

Mache ich daraus ein

             TimerCnt += 4;

dann wird die Zeile ausgeführt....
Kann mir jemand auf die Sprünge helfen was die schief geht?
Gruss,
Gary

von Sebastian (Gast)


Lesenswert?

In deinem Code steht

TimerCnt += 32.0/8.0;

Das ist ein Ausdruck vom Typ "float", schreibt mal (wie oben)

TimerCnt += 32/8; /* Integer-Ausdruck */

Vielleicht klappts dann.

von G. B. (garyb)


Lesenswert?

Sorry das war der letzte Spielstand, aber es ging in jedem Fall nicht.

von G. B. (garyb)


Angehängte Dateien:

Lesenswert?

Da läuft irgendwas im Compiler schief

habe nun ein noch einfachers Beispiel gezimmert...

anbei das Disassembly
@00000030: main
12:       {
+00000030:   E084        LDI     R24,0x04         Load immediate
+00000031:   E090        LDI     R25,0x00         Load immediate
+00000032:   019C        MOVW    R18,R24          Copy register pair
7:          while(--i);
+00000033:   01C9        MOVW    R24,R18          Copy register pair
+00000034:   9701        SBIW    R24,0x01         Subtract immediate 
from word
+00000035:   E024        LDI     R18,0x04         Load immediate
+00000036:   E030        LDI     R19,0x00         Load immediate
+00000037:   F7D1        BRNE    PC-0x05          Branch if not equal
+00000038:   CFFA        RJMP    PC-0x0005        Relative jump
+00000039:   94F8        CLI                      Global Interrupt 
Disable
+0000003A:   CFFF        RJMP    PC-0x0000        Relative jump

von Εrnst B. (ernst)


Lesenswert?

Ist doch alles richtig?

die Delay-Methode wird inline in main reinkopiert, die Berechnungen auf 
Var werden wegoptimiert, weil der berechnete Wert nie verwendet wird.

von G. B. (garyb)


Lesenswert?

@ernst
Das der Compiler hier optimiert habe ich mir auch schon überlegt,
aber deswegen habe ich auch die Option -Os drin gelassen.

hier ein erweitertes Beispiel
#include <stdio.h>
#include <stdint.h>

void Delay( void )
{
  uint16_t i=  0x4;/*1 7FFF;*/
  while(--i);
}


int main(void)
{
  uint8_t Var=0;
  uint8_t Test;

  while ( 1 )
  {
    Delay();
   // Var = 32/8;
      Var = Var+1;
    Test = Var;
    for (Test = 0; Test<= Var; Test++) { }
  }
}

So gehts - nimm die kommentierte Zeile wieder rein - und er macht nichts 
auser dem Delay.

von Εrnst B. (ernst)


Lesenswert?

Dann optimiert dein GCC schlecht.
Bei mir kommt raus:
Version mit "Var=32/8":
1
.L10:
2
        ldi r24,lo8(4)
3
        ldi r25,hi8(4)
4
.L9:
5
        sbiw r24,1
6
        brne .L9
7
        rjmp .L10

Version ohne:
1
        ldi r18,lo8(0)
2
.L4:
3
        subi r18,lo8(-(1))
4
        ldi r24,lo8(0)
5
        ldi r25,hi8(0)
6
.L5:
7
        adiw r24,1
8
        cp r18,r24
9
        brsh .L5
10
        rjmp .L4


Tip:
1
uint16_t i=  0x4;
2
  while(--i);
kann der Compiler optimieren zu:
1
uint16_t i=0;
und wenn i nicht weiter verwendet wird, kann er es ganz rausschmeissen.

Ähnlich:
1
 for (Test = 0; Test<= Var; Test++) { }
Wird zu:
1
  Test=Var+1;

von G. B. (garyb)


Lesenswert?

@ernst...

danke... habe mir nun die brand-aktuelle Version geladen UND
habe gerade festgestellt das -Os ja doch auf Size optimiert.
Mit der Option -O0 ist gut, dann macht er alles richtig...
sorry für die Mühe, aber manchmal ;)
Ich wollte ja nur mein Makro testen ;))

Danke nochmal

von Εrnst B. (ernst)


Lesenswert?

Gerhard Brünner wrote:
> @ernst...
>
> danke... habe mir nun die brand-aktuelle Version geladen UND
> habe gerade festgestellt das -Os ja doch auf Size optimiert.
> Mit der Option -O0 ist gut, dann macht er alles richtig...
>
Richtig macht er es auch mit -Os, zumindest was das Ergebnis anbelangt.

Aber zum ASM-Code anschauen ist -O0 besser geeignet, oder halt auf 
einzelnen Variablen das Optimieren verbieten, mit "volatile"...

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.