2010-12-27 16 views
12
union test 
{ 
int i; 
char ch; 
}t; 
int main() 
{ 
t.ch=20; 
} 

Supponiamo sizeof(int)==2 e lasciare che gli indirizzi di memoria allocata per t sono 2000, 2001.
Allora dov'è 20 vale a dire t.ch conservati - a 2000 o 2001 o dipende endianness della macchina?Come vengono memorizzati i membri del sindacato?

+0

Non sono sicuro se endian-ness abbia qualcosa a che fare con dove viene memorizzata un'unione ... non tutti i tipi di unione vengono archiviati nello stesso percorso (vale a dire allo zero offset)? (Buona domanda però!) –

+3

2001 è improbabile, poiché l'accesso alla memoria non allineato è lento o proibito a seconda dell'architettura. –

+0

@Platinum Azure: se si definisce semplicemente int a = 20; allora non dipende da endianness dove 20 è memorizzato? –

risposta

18

Lo standard C99 (§6.7.2.1.14) dice:

La dimensione di un sindacato è sufficiente a contenere il più grande dei suoi componenti. Il valore di la maggior parte dei membri può essere memorizzato in un oggetto unione in qualsiasi momento. Un puntatore a un oggetto unione, opportunamente convertita, punti a ciascuno dei suoi membri (o se un elemento è un bit- campo, quindi all'unità in cui risiede), e viceversa.

(enfasi aggiunta)

La dichiarazione coraggiosa dice in realtà che ogni membro del sindacato ha lo stesso indirizzo, in modo che tutti "begin" allo stesso indirizzo. t, come t.ch come t.i, deve essere all'indirizzo 2000, quindi t.ch si sovrappone al primo byte (in ordine di indirizzo) di t.i.

Che cosa questo significa in termini di "Che cosa ottengo se provo a leggere t.i dopo aver impostato t.c" nel mondo reale dipende dalla piattaforma endianness, e nei fatti cercando di leggere un membro di un sindacato quando hai scritto in un altro uno è un comportamento non specificato secondo lo standard C (§6.2.6.1.6/7, riformulato al §J.1.1).


Ciò che aiuta di più per capire l'endianness della macchina (almeno, credo che sia più semplice da capire) è quello di avere un'unione come questa:

union 
{ 
    int i; 
    unsigned char ch[sizeof(i)]; 
} t; 

facendo

t.i=20; 

e poi guarda cosa c'è dentro i due caratteri a t.ch. Se sei su una macchina little-endian riceverai t.ch[0]==20 e t.ch[1]==0 e il contrario se sei su una macchina big-endian (se sizeof(int)==2). Si noti che, come già detto, questo è un dettaglio specifico dell'implementazione, lo standard non menziona nemmeno l'endianness.

Per rendere ancora più chiaro: se si dispone di una variabile int a 2 byte impostata su 20, su una macchina little-endian, scaricare la memoria ad essa associata in ordine di indirizzo, si otterrà (in rappresentazione esadecimale, byte raggruppati per lo spazio):

14 00 

mentre su una macchina big-endian si otterrà

00 14 

la rappresentazione big-endian sembra "più giusta" dal nostro punto di vista, perché nel little endian rappresenta i byte che rendono il tutto int vengono memorizzati in ordine inverso.


Inoltre sto dicendo che se faccio questo:

int a=20; 
printf("%d",* (char*)&a); 

poi non l'uscita dipendono endian-ness cioè se 20 è conservato a 2000 o 2001 ?

Sì, eccola, ma nella tua domanda stai chiedendo un'altra cosa; questo sembra più il mio esempio.

+0

Grazie Matteo. In realtà tu e Platinum Azure state dicendo cose opposte, quindi ero confuso. –

+1

@Happy Mittal: Come ho spiegato nel mio ultimo commento ma questo, stavo usando il tuo vecchio commento che aveva una conversione int-to-char. Il fatto rimane: un numero di sedici bit rappresentato dal letterale '20' è ancora memorizzato in ENTRAMBI byte, indipendentemente dalla endianità utilizzata dall'architettura. È solo che un byte o l'altro sarà zero. Se dovessi memorizzare un numero come '257', entrambi i byte saranno diversi da zero. –

1

test richiederebbe due byte e quindi verrebbe assegnato all'indirizzo 2000, 2002, ecc. E qualsiasi valore per ogni istanza dell'unione verrà memorizzato a partire da quell'indirizzo di base.

Ogni membro del sindacato sarà memorizzato allo stesso indirizzo per quell'istanza dell'unione. Questo è il motivo per cui puoi memorizzare un solo tipo di valore in un'unione allo stesso tempo. Pertanto, i sindacati occupano il numero di byte richiesti per il membro più grande.

Problemi correlati