Forum: Mikrocontroller und Digitale Elektronik shift expression has no effect


von Siegfried S. (dieleena)


Lesenswert?

hallo,
bekomme folgende Meldung  " shift expression has no effect "
kann man diese unterdrücken ?
1
    LATD  = (1<< LED_37      )    // out (high = off)
2
          | (1<< LED_36     )    // out (high = off)
3
          | (1<< LED_35     )    // out (high = off)
4
          | (1<< LED_34     )    // out (high = off)
5
          | (1<< LED_33     )    // out (high = off)
6
          | (1<< LED_32      )    // out (high = off)
7
          | (1<< LED_31      )    // out (high = off)
8
          | (1<< LED_30      );   // out (high = off)
Siegfried

von Floh (Gast)


Lesenswert?

warum hat sie keinen Effekt?

von Karl H. (kbuchegg)


Lesenswert?

Floh schrieb:
> warum hat sie keinen Effekt?

dazu müsste man wissen:
wieviele Bits umfasst ein int auf deiner Maschine?
Wie sind die Definitionen für die Makros?

Geraten:
Du bist auf einer 16-Bit int Maschine.
BIT_37 ist ein
1
#define BIT_37  37

Na ja. Wenn du auf deiner Maschine (16 Bit) eine 1 um 37 Stellen nach 
links verschiebst, fällt sie auf jeden Fall aus den möglichen 16 Bit 
raus. Es bleibt also auf jeden Fall 0 über.

Eine plain Vanilla 1 hat den Datentyp int. Mit genau der Bitzahl, die 
ein int eben auf dieser Maschine mit diesem Compiler hat. Und wenn man 
diesen int nur um genügend Stellen nach links verschiebt, dann wird der 
irgendwann auf jeden Fall zu 0, weil alle Bits links rausgefallen sind.

Für jede Zahl x gilt aber

    x | 0  -> x

D.h. das Verodern mit 0 ändert die Zahl nicht. Ergo: Die Operation hat 
keine Auswirkung auf die Zahl selber. Da der Programmierer sich aber 
höchst wahrscheinlich etwas dabei gedacht hat, als er die Veroderung 
geschrieben hat, weist der Compiler darauf hin, das man das besser noch 
einmal prüfen sollte. Den in den meisten Fällen ist das in Summe ein 
Programmierfehler und nicht einfach nur etwas ....

> kann man diese unterdrücken ?

das man ignorieren kann und die Warnung daher unterdrücken sollte.

von Floh (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> dazu müsste man wissen:
> wieviele Bits umfasst ein int auf deiner Maschine?
> Wie sind die Definitionen für die Makros?

Ich hatte die Hoffnung, dass er mir durch sein Antwort mehr Infos 
rausrückt :-)

von Karl H. (kbuchegg)


Lesenswert?

Floh schrieb:
> Karl heinz Buchegger schrieb:
>> dazu müsste man wissen:
>> wieviele Bits umfasst ein int auf deiner Maschine?
>> Wie sind die Definitionen für die Makros?
>
> Ich hatte die Hoffnung, dass er mir durch sein Antwort mehr Infos
> rausrückt :-)

Kannst du vergessen.
An den Namen Siegfried Saueressig kann ich mich aus anderen Threads 
erinnern.

von Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite


Lesenswert?

Karl heinz Buchegger schrieb:
> Und wenn man
> diesen int nur um genügend Stellen nach links verschiebt, dann wird der
> irgendwann auf jeden Fall zu 0, weil alle Bits links rausgefallen sind.

Nein, die ANSI-Spezifikation besagt, dass Schiebeoperationen, die größer 
sind als die Breite des Datentyp, undefiniert sind. Die meisten Compiler 
erzeugen daraus dann aber eine Null.

Es gibt jedoch auch Compiler, die bei höheren Optimierungsstufen einfach 
gar keine Berechnung durchführen und den Registerinhalt einfach so 
belassen, wie er gerade ist.

Dieser Weg wurde von einigen Herstellern gegangen, um bei Benchmarks 
möglichst gut abzuschneiden. Da sie dennoch strikt ANSI-konform sind, 
darf der Tester die Fehlberechnung nicht beanstanden, sondern muss den 
jeweiligen Test als bestanden werten.

Früher gab es auch Grafikkartentreiber, die anhand bestimmer 
Aufrufmuster erkannten, ob ein Benchmark lief. Daraufhin wechselten sie 
in einen speziellen Modus, in dem nicht mehr alle Bildinhalte 
aktualisiert wurden. Dies war aber für den menschlichen Betrachter nicht 
zu erkennen.

von Karl H. (kbuchegg)


Lesenswert?

Andreas Schweigstill schrieb:
> Karl heinz Buchegger schrieb:
>> Und wenn man
>> diesen int nur um genügend Stellen nach links verschiebt, dann wird der
>> irgendwann auf jeden Fall zu 0, weil alle Bits links rausgefallen sind.
>
> Nein, die ANSI-Spezifikation besagt, dass Schiebeoperationen, die größer
> sind als die Breite des Datentyp, undefiniert sind. Die meisten Compiler
> erzeugen daraus dann aber eine Null.

Danke für die Korrektur.
Das war natürlich nicht so gemeint, dass man damit gezielt eine 0 
erzeugen kann, sondern so wie du das auch gesagt hast: In den meisten 
Fällen wird man auf dieses Ergebnis treffen, auch wenn es strikt 
gesprochen undefiniert ist, was passieren soll.

von Siegfried S. (dieleena)


Lesenswert?

Hallo,
ups, habe vergessen, das ich hier mit dem C18 arbeite.
in der *.h ist folgender Code
1
#define  LED_30  7  //  Pin 63  RD7
2
#define  LED_31  6  //  Pin 64  RD6
3
#define  LED_32  5  //  Pin 65  RD5
4
#define  LED_33  4  //  Pin 66  RD4
5
#define  LED_34  3  //  Pin 67  RD3
6
#define  LED_35  2  //  Pin 68  RD2
7
#define  LED_36  1  //  Pin 69  RD1
8
#define  LED_37  0  //  Pin 72  RD0
möchte doch nur in meiner init den Register entsprechende Werte 
übergeben.

wenn ich den C Code in MPLAP GCC nutze, bekomme ich die Warnung nicht.

wie kann man den C Code verbesser, sodas ich das unter C18 sowie GCC 
verwenden kann.

@ Karl heinz Buchegger
>>  Kannst du vergessen.
warum ?

Siegfried

von Lehrmann M. (ubimbo)


Lesenswert?

Siegfried Saueressig schrieb:
> hallo,
> bekomme folgende Meldung  " shift expression has no effect "
> kann man diese unterdrücken ?    LATD  = (1<< LED_37      )    // out (high = 
off)
>           | (1<< LED_36     )    // out (high = off)
>           | (1<< LED_35     )    // out (high = off)
>           | (1<< LED_34     )    // out (high = off)
>           | (1<< LED_33     )    // out (high = off)
>           | (1<< LED_32      )    // out (high = off)
>           | (1<< LED_31      )    // out (high = off)
>           | (1<< LED_30      );   // out (high = off)
> Siegfried

Versuch's mal so:
1
LATD  |= ((1<< LED_37      )    // out (high = off)
2
>           | (1<< LED_36     )    // out (high = off)
3
>           | (1<< LED_35     )    // out (high = off)
4
>           | (1<< LED_34     )    // out (high = off)
5
>           | (1<< LED_33     )    // out (high = off)
6
>           | (1<< LED_32      )    // out (high = off)
7
>           | (1<< LED_31      )    // out (high = off)
8
>           | (1<< LED_30      ));   // out (high = off)

Fazit: Bitmanipulationen nochmal anschauen ... oder den "bösen" Weg 
wählen und die Bits wirklich direkt ansprechen. Ich will aber keinen 
Krieg hier anzetteln ...
Wenn ich dir noch einen Tipp geben darf: Versuch sinnvoller 
auszukommentieren. Wenn du schon überall auskommentierst (bzw. kopierst) 
dann schreib lieber: // LATD.RD0 = 1
oder // LED_34 = on
Das wird dir später helfen ...

Siegfried Saueressig schrieb:
> @ Karl heinz Buchegger
>>>  Kannst du vergessen.
> warum ?
>
> Siegfried

Er kennt deinen Namen - meist ein schlechtes Zeichen. Er scheint dir 
nicht sonderlich friedlich gesonnen zu sein =) ODER ?

Gruß

von Siegfried S. (dieleena)


Lesenswert?

Hallo,
leider das gleiche ergebnis.
Werde dann zwischen GCC und C18 unterschiedliche Zeilen haben.
für die Hilfe vielen Dank.
Siegfried

von 900ss (900ss)


Lesenswert?

Lehrmann Michael schrieb:
> Versuch's mal so:
> LATD  |= ((1<< LED_37      )    // out (high = off) ....

> Fazit: Bitmanipulationen nochmal anschauen ...

Deinen Tip solltest du vllt. erst bei dir anwenden? ;-)
Was macht das: LATD  |= irgendwas
Sicher nicht dasselbe wie: LATD = irgendwas

Ansonsten kann ich mit AVR-GCC den Code oben ohne Warnung übersetzen.
Besser wäre den gesamten Code zu posten, denn wer weiß schon was sich 
hinter LATD verbirgt?

von Karl H. (kbuchegg)


Lesenswert?

Siegfried Saueressig schrieb:

>
1
> #define  LED_30  7  //  Pin 63  RD7
2
> #define  LED_31  6  //  Pin 64  RD6
3
> #define  LED_32  5  //  Pin 65  RD5
4
> #define  LED_33  4  //  Pin 66  RD4
5
> #define  LED_34  3  //  Pin 67  RD3
6
> #define  LED_35  2  //  Pin 68  RD2
7
> #define  LED_36  1  //  Pin 69  RD1
8
> #define  LED_37  0  //  Pin 72  RD0
9
>

OK.
Dann sieht die Sache dann doch jetzt wieder anders aus.

> wenn ich den C Code in MPLAP GCC nutze, bekomme ich die Warnung nicht.

Dann ist dein anderer Compiler wohl wieder einer von der Sorte, der 
gewisse Abstriche in der Standard-Konformität in Kauf nimmt um sich 
besser an 8-Bit Prozessoren anpassen zu können.

Da wird man wohl erst mal identifizieren müssen, welchen Shift er 
anmäkelt :-)
Einzelne Veroderungen auskommentieren, bis die Warnung verschwindet.

Ich tippe mal darauf, dass es sich um diesen Shift hier handelt:
1
      (1<< LED_30      )
(das ist jetzt aber nur ein Schuss ins Blaue!)

Probieren würde ich mal das hier:
1
LATD  |=  ( (1U << LED_37 )    // out (high = off)
2
          | (1U << LED_36 )    // out (high = off)
3
          | (1U << LED_35 )    // out (high = off)
4
          | (1U << LED_34 )    // out (high = off)
5
          | (1U << LED_33 )    // out (high = off)
6
          | (1U << LED_32 )    // out (high = off)
7
          | (1U << LED_31 )    // out (high = off)
8
          | (1U << LED_30 ));   // out (high = off)

um damit den 1-er als unsigned zu markieren und das Signbit still zu 
legen.

von 900ss (900ss)


Lesenswert?

Karl heinz Buchegger schrieb:
> (1<< LED_37      )

Den hab ich auch in Verdacht. Aber wie oben geschrieben, AVR-GCC zickt 
da nicht rum.

von holger (Gast)


Lesenswert?

>Den hab ich auch in Verdacht.

Der ist es auch. Es wird um 0 geschoben. Das hat keinen Effekt;)

> Aber wie oben geschrieben, AVR-GCC zickt
> da nicht rum.

Es geht um PICs.

von Karl H. (kbuchegg)


Lesenswert?

holger schrieb:
>>Den hab ich auch in Verdacht.
>
> Der ist es auch. Es wird um 0 geschoben. Das hat keinen Effekt;)

Nachdem ich die Tomaten von den Augen runtergenommen habe, jep das ist 
es wohl.

von Siegfried S. (dieleena)


Lesenswert?

hallo,
weis das ich hier ein Schreibfehler habe.
> wenn ich den C Code in MPLAP GCC nutze, bekomme ich die Warnung nicht.
habe das auch noch nicht gehört.

sollte doch eine klare möglichkeit geben, C Code aus dem AVR-GCC in 
MPLAP-C18 zu übernehmen, ohne es umschreiben zu müssen.

Siegfried

von Lehrmann M. (ubimbo)


Lesenswert?

900ss D. schrieb:
> Deinen Tip solltest du vllt. erst bei dir anwenden? ;-)
> Was macht das: LATD  |= irgendwas
> Sicher nicht dasselbe wie: LATD = irgendwas

Ja man macht's trotzdem nicht so. Das war auch nur ein Nebenprodukt das 
ich mitkorrigiert hatte. Ich hatte auf die Klammern gesetzt!

von Siegfried S. (dieleena)


Lesenswert?

hallo,

> (1<< LED_37      )
> Den hab ich auch in Verdacht.
> Der ist es auch. Es wird um 0 geschoben. Das hat keinen Effekt;)

richtig, es liegt an dieser zeile, bzw. alle Zeilen, die mit BIT 0 zu 
tun haben.

Siegfried

von (prx) A. K. (prx)


Lesenswert?

Andreas Schweigstill schrieb:

> Nein, die ANSI-Spezifikation besagt, dass Schiebeoperationen, die größer
> sind als die Breite des Datentyp, undefiniert sind.

Fast: ... die grösser oder gleich sind ...

> Die meisten Compiler
> erzeugen daraus dann aber eine Null.

Aber nur wenn die Anzahl dem Compiler bekannt ist. Was zur Laufzeit 
passiert ist eine andere Sache.

von Link zu (Gast)


Lesenswert?

Lehrmann Michael schrieb:
> 900ss D. schrieb:
>> Deinen Tip solltest du vllt. erst bei dir anwenden? ;-)
>> Was macht das: LATD  |= irgendwas
>> Sicher nicht dasselbe wie: LATD = irgendwas
>
> Ja man macht's trotzdem nicht so.
Äh, warum nicht, oben hat er was von einem init geschieben und da wird 
er vielleicht keine alten Einstellungen mit übernehmen wollen.
Ob
LATD  |= irgendwas
oder
LATD   = irgendwas
richtig ist, können wir ohne weitere Informationen nicht wissen.

Karl heinz Buchegger schrieb:
>>>Den hab ich auch in Verdacht.
>> Der ist es auch. Es wird um 0 geschoben. Das hat keinen Effekt;)
> Nachdem ich die Tomaten von den Augen runtergenommen habe, jep das ist
> es wohl.
Also hier meckert der avr-gcc und der gcc nicht.

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.