Forum: Mikrocontroller und Digitale Elektronik Cortex M3 Compiler Warning


von Martin (Gast)


Lesenswert?

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ß

von Little B. (lil-b)


Lesenswert?

du kannst noch die 1 auf uint32_t casten
1
GPIOA->BSRR = (uint32_t)1<<30 | 1<<31;

: Bearbeitet durch User
von Martin (Gast)


Lesenswert?

Wieso kommt eigentlich diese Warnung? Weiß das jemand?
Kann es sein, dass der Compiler eine einfache Zahl nur als 16Bit Int 
interpretiert?

von Peter II (Gast)


Lesenswert?

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?

von (prx) A. K. (prx)


Lesenswert?

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.

von Steffen R. (steffen_rose)


Lesenswert?

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.

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

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.

von Martin (Gast)


Lesenswert?

OK, kann man dem compiler mitteilen, dass 'int' default-mäßig auf 
'unsigned' zu setzen ist?

Sonst mache ich die Variante mit 1U<<x.

von für besseren code (Gast)


Lesenswert?

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);
...

von (prx) A. K. (prx)


Lesenswert?

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?

von für besseren code (Gast)


Lesenswert?

Was schreibst du bei den Anweisungen? Was kann man besser lesen, wenn 7 
Bit in einer Zeile angesprochen werden? ...?

von (prx) A. K. (prx)


Lesenswert?

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
von für besseren code (Gast)


Lesenswert?

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.

von holger (Gast)


Lesenswert?

>Mit #define schreibst du den Sch... nur einmal in der Form.

Und wenn du den Fehler drin lässt hast du ihn dann überall;)

von (prx) A. K. (prx)


Lesenswert?

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.

von für besseren code (Gast)


Lesenswert?

Ja, OK, ich komm wieder runter.
Mit dem #define brauch ich auch nur einmal den Fehler abstellen. ;-)

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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.

von pitschu (Gast)


Lesenswert?

Versuch mal die warning mit -Wno-sign-conversion zu umgehen. Ein Cast 
(uint32_t) ist aber sauberer.

von Bernd K. (prof7bit)


Lesenswert?

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
Noch kein Account? Hier anmelden.