warning: left shift count >= width of type

Gast #825316
Hallo,

folgende Zeile erzeugt mir die Warnung "warning: left shift count >= 
width of type":
1
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
#825322
1
unsigned long int file_size = 
2
 (i2c_get_byte(true) +
3
 (i2c_get_byte(true) << 8) + 
4
 (unsigned long int)(i2c_get_byte(true) << 16)) +
5
 (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.
Gast #825324
wenn i2c_get_byte() als
1
unsigned char i2c_get_byte(...);

vereinbart ist, wird erst mal mit Bytes gerechnet, und die sind nunmal 
acht Bit breit.
Wenn du jetzt
1
(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):
1
unsigned long int file_size =
2
  ((unsigned long int) i2c_get_byte(true) +
3
  ((unsigned long int) i2c_get_byte(true) << 8) +
4
  ((unsigned long int) i2c_get_byte(true) << 16)) +
5
  ((unsigned long int) i2c_get_byte(false) << 24);
Moderator Persönliche Seite #825335
Sven Pauli wrote:

> Wenn du jetzt
>
1
> (i2c_get_byte(true) << 8)
2
>
> 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.
#1359077
Der Beitrag ist zwar schon älter aber ich habe genau das selbe Problem:
Ich habe es so gemacht wie oben beschrieben
1
unsigned long int val =
2
 ((unsigned long int) (*(var->value) << 16)) +
3
 ((unsigned long int) (*((var->value)+1)));
trotzdem bekomme ich die Warnung.
var->value ist int.
AVR-Studio, Optimierung auf -Os
#1374666
Holla zusammen!

Ich habe auch gerade das oben genannte Problem, aber in einer Abfrage:
1
if( x &= (1<<25) )
2
  {
3
  ;
4
  }
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
#1374681
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.
#1374695
@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

Eine eigene Frage? Dieser Thread ist über 18 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.