2014-10-07 18 views
10

correlata ad un previous question, non riesco a capire alcune regole MISRA C 2004.uso di piccoli numeri interi con operatore bit in C

In ISO C99 draft 2007, nella sezione 6.5 § 4:

Alcuni operatori (l'operatore unario ~ e gli operatori binari < <, >>, &, ^, e |, descritti collettivamente come operatori bit a bit) sono richiesti per avere operandi con tipo intero. Questi operatori producono valori che dipendono dalle rappresentazioni interne degli interi e presentano aspetti definiti dall'implementazione e non definiti per i tipi firmati.

Ok, l'utilizzo di un numero intero con segno con operatori bit a bit può produrre un comportamento non definito (e non ha senso).

Una buona soluzione consiste nell'utilizzare la conversione esplicita a un tipo intero senza segno più ampio per bypassare la promozione integrale e quindi non utilizzare il valore con segno con operatori bit per bit (vedere le risposte associate alla mia domanda precedente).

Ma in MISRA C 2004, è possibile utilizzare piccoli numeri interi senza segno con operatori bit a bit (regola 10.5 ad esempio). Perché, se la promozione integrale porta a utilizzare valori firmati con operatori bit a bit? Penso di non capire alcune cose.

+1

Non sono sicuro di aver capito la domanda, ma non dovrebbe importare se un un valore senza segno viene promosso a un tipo più grande. I numeri positivi e i numeri non firmati inferiori al valore massimo firmato sembrano uguali, ovvero il bit del segno è 0. I tipi interi senza segno – Caleb

+0

non daranno luogo a int firmato a causa della promozione integrale. per esempio unsigned short diventerà sempre un int unsigned e mai un int firmato. – mch

+4

@mch Non valido nei sistemi in cui breve e int hanno dimensioni diverse. Se un corto senza segno può rientrare in un 'int', verrà promosso a un' int', che è firmato. – Lundin

risposta

1

Le regole non si contraddicono e non è necessario ampliare il tipo. È possibile eseguire immediatamente il cast del risultato dell'operazione binaria di intero piccolo al suo tipo.

Un piccolo numero intero non verrà promosso a int per i turni a meno che il primo operando non sia int.

Questo è dal loro esempio:

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 questa risposta non è corretta. Vedi C11 6.5.7 'Le promozioni intere sono eseguite su ciascuno degli operandi. Il tipo di risultato è quello dell'operando sinistro promosso. – Lundin

+0

Mi riferivo al risultato, che onora la signness: "Il risultato di E1 >> E2 è E1 con posizioni di bit E2 con spostamento a destra Se E1 ha un tipo senza segno o se E1 ha un tipo firmato e un valore non negativo, il valore del risultato è la parte integrale del quoziente di E1/2E2 " –

+2

E1 e E2 si riferisce agli operandi dopo la promozione di interi. Il testo che citi si riferisce al comportamento scarsamente specificato che si verifica quando si spostano le cose dentro e fuori i bit del segno di un numero negativo. – Lundin

Problemi correlati