www.mikrocontroller.net

Forum: Compiler & IDEs warning: left shift count >= width of type


Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

folgende Zeile erzeugt mir die Warnung "warning: left shift count >= 
width of type":
unsigned long int file_size = (i2c_get_byte(true) + (i2c_get_byte(true) << 8) + (i2c_get_byte(true) << 16)) + (i2c_get_byte(false) << 24);

Wie kann ich diese Warnung unterdrücken?

Der Code soll im Grunde einfach nur eine 4 Byte breite Zahl aus dem 
I2C-EEPROM lesen und entsprechend zusammensetzen.

lg, Peter

Autor: Thomas B. (detritus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
unsigned long int file_size = 
 (i2c_get_byte(true) +
 (i2c_get_byte(true) << 8) + 
 (unsigned long int)(i2c_get_byte(true) << 16)) +
 (unsigned long int)(i2c_get_byte(false) << 24);

Für den Compiler sind solche Konstrukte erstmal ints (hier wohl 16 bit 
lang). Will man mehr um mehr als 15 schieben, muss man auf einen 
grösseren Typ casten.

Edit: Ok, mein Nachfolger hat recht, man muss alles casten. Was ich 
geschrieben hab, gilt für konstante werte, die beim compilieren 
ausgerechnet werden.

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wenn i2c_get_byte() als
unsigned char i2c_get_byte(...);

vereinbart ist, wird erst mal mit Bytes gerechnet, und die sind nunmal 
acht Bit breit.
Wenn du jetzt
(i2c_get_byte(true) << 8)
machst, rechnen wir immer noch mit den 8-Bit breiten Bytes, aber du 
schiebst quasi mit "<<8" bis hin zur 16. Stelle nach links, und das geht 
beim Byte eben nicht.

Lösung: Zwing dem Compiler was Breiteres auf (Casting):
unsigned long int file_size =
  ((unsigned long int) i2c_get_byte(true) +
  ((unsigned long int) i2c_get_byte(true) << 8) +
  ((unsigned long int) i2c_get_byte(true) << 16)) +
  ((unsigned long int) i2c_get_byte(false) << 24);

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

Bewertung
0 lesenswert
nicht lesenswert
Sven Pauli wrote:

> Wenn du jetzt
>
> (i2c_get_byte(true) << 8)
> 
> machst, rechnen wir immer noch mit den 8-Bit breiten Bytes, ...

Nein, machen wir nicht.  Wir rechnen dann mit `int' (aber mit einem
vorzeichenbehafteten!), weil das die integer promotion rules der
Sprache C so verlangen.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wow, bin wieder einmal beeindruckt von den prompten Antworten hier :-)

Vielen Dank,
jetzt funktioniert alles!

lg, Peter

Autor: Phillip Hommel (philharmony)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Beitrag ist zwar schon älter aber ich habe genau das selbe Problem:
Ich habe es so gemacht wie oben beschrieben
unsigned long int val =
 ((unsigned long int) (*(var->value) << 16)) +
 ((unsigned long int) (*((var->value)+1)));  
trotzdem bekomme ich die Warnung.
var->value ist int.
AVR-Studio, Optimierung auf -Os

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Phillip Hommel schrieb:

>  ((unsigned long int) (*(var->value) << 16)) +

Stall zugesperrt als das Pferd schon ausgebüchst ist.

Autor: Phillip Hommel (philharmony)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ah, du meinst daß das Bit-Schieben eine Klammer zu weit "innen" erfolgt?

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Phillip Hommel schrieb:

> Ich habe es so gemacht wie oben beschrieben

Nein, hast du nicht. Du musst "*(var->value)" casten, nicht das Ergebnis 
vom Shift.

Autor: Phillip Hommel (philharmony)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jo, hab den feinen Unterschieb bemerkt.
Danke ;)

Autor: Joachim B. (jojo84)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Holla zusammen!

Ich habe auch gerade das oben genannte Problem, aber in einer Abfrage:
if( x &= (1<<25) )
  {
  ;
  }
Erklärt sihc ja eigentlich von selbst: x ist ein long und ich will Bit 
25 abfragen.
Aber ich check nicht ganz, wo ich dann casten muß.
Würd mich freuen, wenn mich jemand fix aufklärt :)

VG

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
1L<<25

Autor: Joachim B. (jojo84)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ A.K.:
OH!
Das ist ja toll! DANKE!

Kannst du mir vielleicht auch kurz erklären, warum das so ist? einfach 
eintippern ist zwar schön einfach, aber ich würd das gern verstehen :)

VG

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bist du sicher, dass du dort ein "&=" haben möchtest?

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Joachim A. schrieb:

> Kannst du mir vielleicht auch kurz erklären, warum das so ist? einfach
> eintippern ist zwar schön einfach, aber ich würd das gern verstehen :)

Weil die 1 sonst nur ein int ist, also 16 Bit groß.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Joachim A. schrieb:

> Kannst du mir vielleicht auch kurz erklären, warum das so ist? einfach
> eintippern ist zwar schön einfach, aber ich würd das gern verstehen :)

1L ist (long)1

Wenn dir das auch nix nützt, dann solltest du mal einen Blick in ein C 
Handbuch riskieren.

Autor: Joachim B. (jojo84)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Stefan:
Ups, da mit dem "&=" hab ich nicht aufgepasst, danke ;) ...
Und die Erklärung hat auch geholfen. Ich mach jetzt schon ne weile C, 
aber ich hab nie darüber nachgedacht, daß Konstante, wie die 1 da, auch 
int's sind...

Aber ok, wieder was gelernt :)

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.