(uint16_t)(~(uint16_t) CONST) - was will der Autor damit sagen?

Gast #3628799
Lesenswert?

Hallo zusammen,
in einer Headerdatei zum ARM-GCC (stm32F10x_tim.c) steht folgende Zeile
1
TIMx->CCER &= (uint16_t)(~(uint16_t)TIM_CCER_CC1E);

Was will der Autor damit eigentlich sagen? Was bewirkt der Doppel-Cast 
mehr als nur
1
TIMx->CCER &= ~(uint16_t) TIM_CCER_CC1E;
?

Und wenn nichts: Wie entstehen solche Konstrukte? Codegenerierung?

Viele Grüße
W.T.
#3628839
Lesenswert?

Walter Tarpan schrieb:
> Hallo zusammen,
> in einer Headerdatei zum ARM-GCC (stm32F10x_tim.c) steht folgende Zeile
>
1
> TIMx->CCER &= (uint16_t)(~(uint16_t)TIM_CCER_CC1E);
2
>
>
> Was will der Autor damit eigentlich sagen? Was bewirkt der Doppel-Cast
> mehr als nur
>
1
> TIMx->CCER &= ~(uint16_t) TIM_CCER_CC1E;
2
>
> ?
>
> Und wenn nichts: Wie entstehen solche Konstrukte? Codegenerierung?

Wenn alle GCC Warnungen eingeschaltet sind, gibt die Zeile
1
TIMx->CCER &= ~(uint16_t) TIM_CCER_CC1E;
Fehler, da ein 32 Bit-Wert auf eine 16-Bit Variable geschrieben wird. 
Das ist ein Fehler, der beabsichtigt wird. Damit der Compiler die 
Warnung unterlässt, wird nochmals auf 16 Bit gecastet. Damit hält der 
Code auch einem MISRA Test stand.
#3628912
Lesenswert?

The Harper schrieb:
> Bitflüsterer schrieb:
>> Das ganze Thema hat mit "Integer Promotion" und "Impliziter
>> Typumwandlung" zu tun. Lies das mal nach.
>
> Exakt. Die Typumwandlung
> (http://de.wikipedia.org/wiki/Promotion_%28Typumwandlung%29) wird
> spätestens durch den Bitweise-Negations-Operator ~ ausgelöst.

Das ist ja alles richtig, erklärt aber nicht den inneren cast.
1
TIM_CCER_CC1E
nach uint16_t zu casten macht nicht so fürchterlich viel Sinn - es ist 
ja (zumindest in den Headern, die ich hier habe) schon als uint16_t 
deklariert.
Moderator #3628944
Lesenswert?

Markus F. schrieb:
> Das ist ja alles richtig, erklärt aber nicht den inneren cast.
> TIM_CCER_CC1Enach uint16_t zu casten macht nicht so fürchterlich viel
> Sinn - es ist
> ja (zumindest in den Headern, die ich hier habe) schon als uint16_t
> deklariert.

Ja, und selbst wenn der uint16_t-Cast im Header fehlen würde, wäre es
unsinnig, den Wert erst explizit nach uint16_t zu casten, wenn er
anschließend sowieso wieder auf 32 Bit erweitert wird. So etwas würde
man höchstens dann machen, wenn man die oberen 16 Bit ausmaskieren will,
was hier aber sicher nicht der Fall ist, zumal TIM_CCER_CC1E den Wert 1
hat und somit alle höherwertigen Bits sowieso schon 0 sind.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren