2015-02-04 16 views
16

Durante la lettura attraverso alcuni codici di esempio per DMA da Xilinx, mi sono imbattuto in questo pezzo di codice:Perché questo codice per l'incremento di uint8_t include `& 0xFF`?

value = (value + 1) & 0xFF 

cui valore è un uint8_t.

Qual è il punto dello & 0xFF? Perché non scrivere semplicemente value = value + 1?

+15

Sembra un programmatore esperto che è stato masterizzato dai compilatori in precedenza. Quel codice funziona anche dopo che qualcuno è arrivato più tardi e ha cambiato uint8_t o ha cambiato la definizione di uint8_t ... –

+7

In alternativa è stato usato un artefatto di codice scritto prima di 'uint8_t'. – Persixty

+0

Questo programmatore stava cercando per noi. Lui/lei ha reso ovvio che 'valore' è inteso per essere un valore a 8 bit e non dobbiamo neanche andare a cercare la dichiarazione. – kkrambo

risposta

18

La mia ipotesi è che questo codice è stato progettato per funzionare correttamente anche se value è non un tipo di 1 byte (8 bit). La maschera di bit 0xFF si assicura che sia mantenuto solo l'ultimo byte del valore.

+1

Per 1 byte, suppongo si intenda veramente a 8 bit. Quel programmatore era molto probabilmente un po 'obsoleto con un carattere non 8 bit, quindi in seguito ha cambiato il carattere in uint8_t ma ha mantenuto la maschera. – user3528438

+0

@ user3528438: sì, penso anche che una cosa del genere sia successo. Ma forse non lo sapremo mai ... – Mints97

+2

La conversione a 'uint8_t' durante l'assegnazione garantisce già che sia mantenuto solo l'ultimo byte del valore. Quindi non credo che questa risposta sia corretta. Più probabilmente, il mascheramento serve a disattivare gli avvisi del compilatore causati dalla promozione di interi. Vedi la mia risposta. – Lundin

10

Questo tipo di codice è comune quando si desidera evitare problemi con implicit type promotions o quando si desidera semplicemente dimostrare di aver preso in considerazione le promozioni implicite durante la scrittura del codice, che è una buona pratica di programmazione.

uint8_t è un tipo intero piccolo e pertanto sempre promosso a int ogni volta che lo si utilizza in un'espressione. Il risultato di (value + 1) è sempre int.

Senza il mascheramento, alcuni compilatori forniscono avvisi come "tentare di memorizzare int in uint8_t". Ho riscontrato tali avvertimenti su diversi compilatori. Teoricamente int & 0xFF è ancora un int, ma dal momento che non può avere un valore maggiore di 0xFF, il compilatore è probabilmente in grado di ottimizzare il tipo fino a uint8_t e l'avviso andrà via.

In alternativa è possibile scrivere value = (uint8_t)(value + 1u); che ha lo stesso significato (ma è una versione MISRA-C compatibile del codice).

+0

Per motivi di completezza, questo è chiamato "applicare una maschera". Eseguendo un'operazione "logica e" con 0xFF (255), si disattivano tutti i bit che renderebbero il valore maggiore della maschera.Quindi questo agisce come valore incrementale e lo ripristina a 255 se supera questo valore. –

+2

@ user2010913 intendete 0, non 255. – Quentin

+0

@Quentin, 0xFF è 255, se il valore supera 255 sarà sempre 255 (non 0) –

Problemi correlati