2010-03-24 9 views
11

Sono puntatori su un sistema a 64 bit ancora allineato a 4 byte (simile a un doppio su un sistema a 32 bit)? O sono allineati con 8 byte?C Allineamento puntatore a 64 bit

Ad esempio, in un sistema a 64 bit quanto è grande la seguente struttura dati:

struct a { 
    void* ptr; 
    char myChar; 
} 

Sarebbe il puntatore 8 byte allineati, causando 7 byte di riempimento per il personaggio (totale = 8 + 8 = 16)? O il puntatore dovrebbe essere allineato a 4 byte (4 byte + 4 byte) causando 3 byte di padding (totale = 4 + 4 + 4 = 12)?

Grazie, Ryan

+7

Per un momento, ho letto "C64". – Thilo

risposta

6

L'allineamento e il riempimento dei dati sono specifici dell'implementazione e possono essere in genere modificati dalle impostazioni del compilatore (o anche con i comandi).

Tuttavia, supponendo che si stiano utilizzando le impostazioni predefinite, sulla maggior parte (se non tutti) i compilatori la struttura dovrebbe finire con 16 byte totali. Il motivo è che i computer leggono un chunk di dati con dimensioni della sua dimensione nativa (che è 8 byte nel sistema a 64 bit). Se fosse necessario eseguire il rilievo su offset a 4 byte, la struttura successiva non sarebbe adeguatamente riempita al limite a 64 bit. Ad esempio, nel caso di un arr [2], il secondo elemento dell'array inizierà con un offset di 12 byte, che non si trova al confine nativo del byte della macchina.

6

non credo che si può fare affidamento su alcuna regola duro e veloce. Penso che sia una funzione del compilatore che usi e delle opzioni di compilazione che scegli.

La soluzione migliore è scrivere un programma che verifica ciò e sputa un file di intestazione che codifica le regole di allineamento come #define s. Potresti anche essere in grado di calcolare anche ciò che ti interessa direttamente nei macro.

3

Generalmente su un sistema a 64 bit:

struct a { 
    void* ptr;  // size is 8 bytes, alignment is 8 
    char myChar; // size is 1 byte, alignment is 1 
        // padding of 7 bytes so array elements will be properly aligned 
} 

per un totale di 16 byte.

Ma questa è tutta l'implementazione definita - sto solo dando un esempio che potrebbe essere vero per molti (la maggior parte?) Sistemi a 64 bit.

0

È necessario consultare la documentazione per il particolare ABI a cui si è interessati. Ad esempio, qui è the System V ABI x86-64 architeture supplement - è possibile vedere a pagina 12 che i puntatori su questo ABI sono allineati a 8 byte (quindi sì, la struttura si mostra sarebbe riempito fino a 16 byte).

1

Lo standard di lingua non rende dichiarazioni sul riempimento. Le regole di allineamento sono specifiche della piattaforma (cioè, devi allineare in modo diverso, ad esempio una CPU PowerPC rispetto a una CPU x86_64), e sono definite dall'implementazione, il che significa che il tuo compilatore può fare tutto ciò che funziona (e potrebbe cambiare quel comportamento con un comando diverso -line opzioni o dopo un aggiornamento della versione).

Sono fermamente convinto che qualsiasi raccomandazione sulla falsariga di "questo è di solito questo o quello" è fuorviante e potenzialmente pericolosa.

  1. si potrebbe scrivere un programma di test che esegue un paio di sizeof() e/o offsetof() dichiarazioni e scrive un colpo di testa per te contenente alcune #define s indicante le imbottiture utilizzate.

  2. È possibile utilizzare autoconf per farlo.

  3. Per lo meno, è necessario aggiungere le istruzioni assert(sizeof(...)) all'inizio della funzione main() in modo da essere informati quando le ipotesi sono errate.