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.
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ò!) –
2001 è improbabile, poiché l'accesso alla memoria non allineato è lento o proibito a seconda dell'architettura. –
@Platinum Azure: se si definisce semplicemente int a = 20; allora non dipende da endianness dove 20 è memorizzato? –