2015-07-24 10 views
6

Ho la seguente struttura e la funzione "getter" che ritorna a Cast a un intero senza segno:Casting tipi di puntatore su diverse architetture

struct s { 
    uint32_t a; 
}; 

void get_a(struct s *st, unsigned *ret) 
{ 
    *ret = (unsigned)st->a; 
} 

Il seguente codice viene eseguito:

struct s st; 
uint16_t x; 

st.a = 1; 
get_a(&st, (unsigned *)&x); 

e per x86_64, i686, armv7hl, ppc64le e altre architetture x == 1, ma per ppc64 x == 0. Perchè è questo? Poco - big-endian?

+0

Impostare a a 0x12345678. Le macchine little-endian restituiranno 0x5678, big-endian 0x1234. Per mantenere lo stesso comportamento su tutte le macchine usa le funzioni htonl/htons/ntohl/ntohs. – nsilent22

risposta

5

Il problema è che avete:

uint16_t x; 

ma poi si tenta di scrivere in quella posizione di memoria come se fosse la posizione di unsigned.

Se si era su un sistema in cui unsigned e uint16_t sono dello stesso tipo, questo va bene. Ma su altri sistemi, come quello che hai usato per il tuo esempio di codice, sei nei guai.

Prima di tutto, ciò causa undefined behaviour violando lo strict aliasing rule. Le variabili di tipo uint16_t possono essere scritte solo tramite lvalue di tipo uint16_t o un tipo di carattere.

Ma anche se non violasse il rigoroso aliasing, si causerebbe comunque UB scrivendo al di fuori dei limiti di x. Probabilmente, stai scrivendo 4 o 8 byte in una posizione di memoria a 2 byte, quindi si riverserà il buffer.

Ci potrebbe anche essere UB se x non è correttamente aligned per unsigned.

+0

Penso che valga la pena ricordare che endianness non ha nulla a che fare in questo caso. – edmz

+1

@black fa un po 'di cose: * se * tutto l'UB nel codice non produce demoni nasali questa volta, potremmo aspettarci che il bit '1' in fase di scrittura sia visualizzato all'interno di' x' o all'esterno di 'x' sul sistema endianness –

+1

Lezione appresa: non lanciare i puntatori, o almeno fare molta attenzione con quello che stai facendo. C'è sempre una soluzione diversa. Qui una variabile tipizzata 'non firmata' temporanea avrebbe spazzato via tutte le incertezze. – alk

Problemi correlati