Hallo, wenn ich ein 32Bit Register beschreibe, kommt es zu Warnings. z.B. GPIOA->BSRR = 1<<30 | 1<<31; Warning: Integer out of range (oder irgendwie so) Das Problem kann ich leicht lösen, indem ich schreibe: GPIOA->BSRR = 1UL<<30 | 1UL<<31; jedoch finde ich das nicht so elegant. Wie kann ich dem Compiler denn noch mitteilen, dass er die 1<<x als 32Bit unsigned wahrnimmt? Gruß
du kannst noch die 1 auf uint32_t casten
1 | GPIOA->BSRR = (uint32_t)1<<30 | 1<<31; |
:
Bearbeitet durch User
Wieso kommt eigentlich diese Warnung? Weiß das jemand? Kann es sein, dass der Compiler eine einfache Zahl nur als 16Bit Int interpretiert?
Martin schrieb: > Wieso kommt eigentlich diese Warnung? Weiß das jemand? > Kann es sein, dass der Compiler eine einfache Zahl nur als 16Bit Int > interpretiert? der Compiler rechnen mit int - wie groß ist denn int bei dem Cortex M3?
Martin schrieb: > Wie kann ich dem Compiler denn > noch mitteilen, dass er die 1<<x als 32Bit unsigned wahrnimmt? Genau so wo wie du es getan hast, wobei das "L" überflüssig ist. Wenn dir diese Schreibarbeit zu viel ist, dann nimm einen 64-Bit Prozessor in einer Umgebung mit sizeof(int)==8.
Was ist an 1ul unelegant?
1 | GPIOA->BSRR = 1UL<<30 | 1UL<<31; |
2 | GPIOA->BSRR = (uint32_t)1<<30 | (uint32_t)1<<31; |
"int == signed int" zu shiften erscheint mit hier nicht sinnvoll und wird die Warnung erzeugen (> 0x7FFFFFFF). Ein 'unsigned' Typ mach mehr Sinn.
Martin schrieb: > Wieso kommt eigentlich diese Warnung? Weiß das jemand? > Kann es sein, dass der Compiler eine einfache Zahl nur als 16Bit Int > interpretiert? Mit einem signed 32 bit integer ist 2^31 nicht mehr darstellbar.
OK, kann man dem compiler mitteilen, dass 'int' default-mäßig auf 'unsigned' zu setzen ist? Sonst mache ich die Variante mit 1U<<x.
Martin schrieb: > Wieso kommt eigentlich diese Warnung? Weiß das jemand? > Kann es sein, dass der Compiler eine einfache Zahl nur als 16Bit Int > interpretiert? Die Warnung bekommst du für die bescheuerte Schreibweise mit <<. Wenn man das so dämlich schreiben will, dann bitte mit Makro #define BIT(X) ((uint32_t)(1<<(X))) ... PortA = BIT(30) | BIT(1); ...
für besseren code schrieb: > Wenn man das so dämlich schreiben will, dann bitte mit Makro > #define BIT(X) ((uint32_t)(1<<(X))) Soll das jetzt die bessere oder die dämlichere Version sein?
Was schreibst du bei den Anweisungen? Was kann man besser lesen, wenn 7 Bit in einer Zeile angesprochen werden? ...?
für besseren code schrieb: > Was kann man besser lesen Man kann sich zwar bei Geschmacksfragen auch freundlicher ausdrücken als du, aber das ist nicht das Problem. Du sperrst den Stall erst zu, nachdem das Pferd schon ausgebüxt ist.
:
Bearbeitet durch User
Mit #define schreibst du den Sch... nur einmal in der Form. Im Rest der Source bleibts leserlich. Und schöner ausdrücken kann man das nicht. Wenn ich Quelltexte mit der Shifterei sehen muss und dann 5 Bits oder mehr gesetzt werden, ist das einfach nur Bullshit.
>Mit #define schreibst du den Sch... nur einmal in der Form.
Und wenn du den Fehler drin lässt hast du ihn dann überall;)
Grad ein bissel stur drauf? ;-) Es geht nicht um die Ästhetik. Sondern um den Überlauf bei 1<<31. Und der wird bei dir nicht besser, denn in (uint32_t)(1<<31) kommt der Cast zu spät um den Überlauf zu verhindern.
Ja, OK, ich komm wieder runter. Mit dem #define brauch ich auch nur einmal den Fehler abstellen. ;-)
Martin schrieb: > OK, kann man dem compiler mitteilen, dass 'int' default-mäßig auf > 'unsigned' zu setzen ist? Nein. int ist signed. Suehe Standard. 1 << 31 ist Undefined Behaviour (Signed Overfloe) falls int <= 32 Bit. Einfachste Lösung ist 1L << 31. Falls definiertes Verhalten (mod 2^32) auch benötigt wird geht z.B. -fwrapv.
Versuch mal die warning mit -Wno-sign-conversion zu umgehen. Ein Cast (uint32_t) ist aber sauberer.
Martin schrieb: > GPIOA->BSRR = 1UL<<30 | 1UL<<31; bei mir sähe sowas eher so aus:
1 | #define HAUPTSTEUERKONTROLLE (GPIOA)
|
2 | |
3 | #define WARPANTRIEB (1U << 29)
|
4 | #define IMPULSANTRIEB (1U << 30)
|
5 | #define TRAEGHEITSDAEMPFER (1U << 31)
|
und an anderer Stelle:
1 | HAUPTSTEUERKONTROLLE->BSSR = IMPULSANTRIEB | TRAEGHEITSDAEMPFER; |
Das macht den Code leserlicher. Ich höre in der Regel erst auf wenn nirgendwo mehr außerhalb einer Headerdatei namenlose Konstanten auftauchen die keinen verdammt guten Grund für ihre Anwesenheit dort vorweisen können.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.