2014-10-07 6 views
10

Bezug zu einem previous question, kann ich nicht einige Regeln von MISRA C 2004Verwendung von kleiner ganzer Zahl mit Bits Operator in C

In ISO C99 draft 2007, in 6,5 Abschnitt §4 verstehen:

Einige Betreiber (der unäre Operator ~ und die binären Operatoren < <, >>, &,^und |, zusammen als bitweise Operatoren beschrieben) müssen Operanden haben, die einen Integer-Typ haben. Diese Operatoren liefern Werte, die von den internen Repräsentationen von Ganzzahlen abhängen, und sie haben implementierungsdefinierte und undefinierte Aspekte für signierte Typen.

Ok, die Verwendung einer vorzeichenbehafteten Ganzzahl mit bitweisen Operatoren kann zu undefiniertem Verhalten führen (und ergibt keinen Sinn).

Eine gute Lösung ist die explizite Konvertierung in einen breiteren, vorzeichenlosen Integer-Typ, um die integrale Heraufstufung zu umgehen und dann keinen signierten Wert mit bitweisen Operatoren zu verwenden (siehe zugehörige Antworten meiner vorherigen Frage).

Aber in MISRA C 2004 ist die Verwendung kleiner vorzeichenloser Ganzzahlen mit bitweisen Operatoren möglich (Regel 10.5 zum Beispiel). Warum, wenn integrale Werbung dazu führt, signierte Werte mit bitweisen Operatoren zu verwenden? Ich denke, ich verstehe einige Dinge nicht.

+1

Ich bin mir nicht sicher, ob ich die Frage verstehen, aber es sollte keine Rolle, ob ein Wert ohne Vorzeichen zu einem größeren Typ gefördert wird. Positive Zahlen und vorzeichenlose Zahlen, die kleiner als der Wert mit maximalem Vorzeichen sind, sehen gleich aus, d. H. Das Vorzeichenbit ist 0. – Caleb

+0

vorzeichenlose Integer-Typen ergeben aufgrund der ganzzahligen Heraufstufung kein signed int. Zum Beispiel wird unsigned short immer zu einem unsigned int und niemals zu einem signed int. – mch

+4

@mch Nicht wahr auf Systemen, wo kurz und int unterschiedliche Größe haben. Wenn ein vorzeichenloser short in ein 'int' passen kann, wird er in ein' int' befördert, das signiert ist. – Lundin

Antwort

1

Die Regeln widersprechen sich nicht und Sie müssen den Typ nicht erweitern. Sie können das Ergebnis der binären Operation mit kleinen Ganzzahlen sofort auf den Typ zurückgeben.

Eine kleine Ganzzahl wird nicht in int für Verschiebungen hochgestuft, es sei denn, der erste Operand ist int.

Dies ist von ihrem Beispiel:

uint8_t port = 0x5aU; 
uint8_t result_8; 
uint16_t result_16; 

result_8 = (~port) >> 4; /* not compliant */ 
result_8 = ((uint8_t)(~port)) >> 4; /* compliant */ 
result_16 = ((uint16_t)(~(uint16_t)port)) >> 4; /* compliant */ 
+4

-1 Diese Antwort ist nicht korrekt. Siehe C11 6.5.7 'Die Integer-Promotions werden für jeden der Operanden durchgeführt. Der Typ des Ergebnisses ist der des beförderten linken Operanden. " – Lundin

+0

Ich bezog mich auf das Ergebnis, das Signedness ehrt:" Das Ergebnis von E1 >> E2 ist E1 rechtsverschobene E2-Bitpositionen. Wenn E1 einen vorzeichenlosen Typ hat oder wenn E1 einen vorzeichenbehafteten Typ und einen nicht negativen Wert hat, ist der Wert des Ergebnisses der ganzzahlige Teil des Quotienten von E1/2E2 " –

+2

E1 und E2 bezieht sich auf die Operanden nach der Ganzzahl-Heraufstufung. Der von Ihnen zitierte Text bezieht sich auf das schlecht spezifizierte Verhalten, das auftritt, wenn Sie Dinge in die Zeichenbits einer negativen Zahl hinein- und hinausschieben. – Lundin