Manipolare l'indirizzo di una variabile per memorizzare un tipo più piccolo?
-
24-10-2019 - |
Domanda
Questo è ciò che ho per coccolare me stesso con i linguaggi di programmazione di alto livello.
Ho una funzione che scrive un valore a 32 bit in un buffer e un uint64_t
in pila. È il seguente codice di un modo sano per conservarlo?
uint64_t size = 0;
// ...
getBytes((uint32_t*)&size+0x1);
sto supponendo che questa sarebbe la canonica, stile sicuro:
uint64_t size = 0;
// ...
uint32_t smallSize;
getBytes(&smallSize);
size = smallSize;
Soluzione
No. Esso funziona correttamente solo su macchine big-endian. E assumendo un particolare ordine di byte - senza nemmeno controllarlo prima - non è sano.
Anche se si è certi che il programma funziona solo su macchine big-endian in questo momento, non saprai mai se si potrebbe avere per l'esecuzione su un little-endian macchina in futuro. (Sto scrivendo questo su un computer realizzato da una società che ha utilizzato big-endian processori per decenni, poi passato a processori little-endian un paio di anni fa, e ora è anche un discreto successo con processori bi-endian in alcuni dispositivi; - ))
Altri suggerimenti
Perché non fare getBytes () per tornare uint64_t? E utilizzare l'argomento (per esempio int *) per restituire il codice di errore se del caso.
Dalla mia esperienza personale, se si vuole veramente di unificare i due percorsi di codice, quindi utilizzare uint64_t in entrambi.
Si noti inoltre che "(uint32_t *) e dimensioni" pause C99 severe norme di aliasing (e per esempio in GCC si dovrebbe disabilitare l'ottimizzazione).