Integer promotion - Ich raff's nicht

OP #4089006
Lesenswert?
• ▲
▼
Hallo zusammen,
ich sitze hier mit dem K&R und wundere mich. Im folgenden Quelltext:
1
static inline __attribute__((always_inline)) void
2
ClearBit(GPIO_TypeDef * const GPIOx, const uint16_t bit) 
3
{
4
    GPIOx->BSRR = bit<<16U;
5
}
warnt mich der ARM-GCC zu der einzigen aktiven Zeile:
"30: warning: conversion to 'uint32_t' from 'int' may change the sign of 
the result [-Wsign-conversion]"

Das Feld "BSRR" ist übrigens als Zeiger auf uint32_t deklariert.

OK, was passiert hier? "bit" paßt in einen 32-Bit-Integer, wird also in 
einen solchen konvertiert. 16U passt nicht hinein und bleibt deshalb ein 
unsigned int. Um die Schiebeoperation durchführen zu können, wird 
anschließend "bit" vom Int -in das es vorher konvertiert wurde- in ein 
unsigned Int konvertiert - hier tritt der mögliche Datenverlust auf und 
der GCC warnt mich.

Mit der Änderung
1
GPIOx->BSRR = (uint32_t) bit<<16U;
wird "bit" direkt passend kovertiert und der Zwischenschritt über einen 
signed integer bleibt aus. Habe ich das richtig verstanden?

Viele Grüße
W.T.
Gast #4089476
Lesenswert?
• ▲
▼
> "bit" paßt in einen 32-Bit-Integer, wird also in  einen solchen konvertiert.

Nein.  Integer-Arithmetik findet immer in mindesten int-Größe statt (wie 
groß auch immer das ist).  bit (ein uint16_t) ist auf ARM kleiner als 
int (32 Bit), also wird es zu int erweitert.  Auf Systemen mit 
16-Bit-Ints bliebe es ein uint16_t.

> 16U passt nicht hinein und bleibt deshalb ein unsigned int.

Ist egal, ist ein (unsigned) int, bleibt auch einer.  Btw, das U ist 
unnötig.

> Um die Schiebeoperation durchführen zu können, wird anschließend "bit" vom
> Int -in das es vorher konvertiert wurde- in ein  unsigned Int konvertiert

Nein, der int-Wert wird 16-mal nach links geschoben, Resultat ist wieder 
ein int.  Vorsicht bei 16-Bit-Int-Systemen!

> - hier tritt der mögliche Datenverlust auf und der GCC warnt mich.

Nein, die Warnung kommt bei der Zuweisung eines (signed) int an ein 
uint32_t.

> Mit der Änderung
1
    GPIOx->BSRR = (uint32_t) bit<<16U;
> wird "bit" direkt passend kovertiert und der Zwischenschritt über einen
> signed integer bleibt aus. Habe ich das richtig verstanden?

Genau.  Und nur so auf Systemen mit 16-Bit-Ints korrekt.

Btw, der cast bezieht sich auf bit, nicht auf das Ergebnis des Shifts. 
Ich würde die Leerstellen deshalb anders setzen:
1
    GPIOx->BSRR = (uint32_t)bit << 16;
#4089479
Lesenswert?
• ▲
▼
Während bei Operatoren wie + und * das Vorzeichen der rechten Seite 
genau wie der linken Seite den Typ des Ergebnisses bestimmt, ist das bei 
den Shift-Operatoren nicht der Fall. Weshalb das U in 16U hier also 
nichts am Vorzeichentyp des Ergebnisses ändert. Folglich ist "bit << 
16U" bei 32-Bit ein "int", "bit + 16U" aber ein "unsigned".
#4089481
Lesenswert?
• ▲
▼
NB: Auf 32-Bit Maschinen wie diesem ARM ergibt es generell wenig Sinn, 
in Parametern und lokalen Variablen einen kleineren Typ als 32 Bits zu 
verwenden. Ausser es geht darum, den Wertebereich vorsätzlich darauf 
einzuschränken um keine anderen Werte zuzulassen. Dagegen kann die 
Verwendung kleinerer Typen bei ARMs zu umständlicherem Code führen, da 
es in Registern dafür keine Befehle gibt.

Antwort schreiben

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.

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.