2011-12-07 9 views
5

In base a MSDN, il comando /Zp assume come valore predefinito 8, il che significa che vengono utilizzati i limiti di allineamento a 64 bit. Ho sempre pensato che per le applicazioni a 32 bit, il compilatore MSVC utilizzerà i limiti a 32 bit. Per esempio:Allineamento memoria predefinita MSVC di 8

struct Test 
{ 
    char foo; 
    int bar; 
}; 

il compilatore pad in questo modo:

struct Test 
{ 
    char foo; 
    char padding[3]; 
    int bar; 
}; 

Quindi, dal momento che /Zp8 viene utilizzato per default, significa che il mio imbottitura diventa 7 + 4 byte utilizzando lo stesso esempio di cui sopra:

struct Test 
{ 
    char foo; 
    char padding1[7]; 
    int bar; 
    char padding2[4]; 
}; // Structure has 16 bytes, ending on an 8-byte boundary 

Questo è un po 'ridicolo, non è vero? Sto fraintendendo? Perché è utilizzata una così grande imbottitura, sembra uno spreco di spazio. La maggior parte dei tipi su un sistema a 32 bit non utilizzerà nemmeno i 64 bit, quindi la maggior parte delle variabili avrebbe il padding (probabilmente oltre l'80%).

+0

Puoi chiarire il '7 + 4'? Sono alquanto confuso dalla domanda in questo momento. – Mysticial

+0

@Mysticial: Ho aggiornato il mio OP con un altro esempio per mostrarvi cosa intendo con questo. Dispiace per la confusione. –

+0

Grazie per il chiarimento. Ho appena testato la tua prima struttura e la dimensione è di soli 8 byte, riempita con il secondo snippet di struct. Quindi non sono in grado di riprodurre ciò che stai ricevendo. (o almeno quello che pensi che dovresti ottenere) – Mysticial

risposta

8

Non è così che funziona. I membri sono allineati a un multiplo della loro dimensione. Char a 1 byte, short a 2, int a 4, double a 8. La struttura viene riempita alla fine per garantire che i membri siano ancora allineati correttamente quando la struct viene utilizzata in una matrice.

impacchettatrice di 8 significa che interrompe che tenta di allineare i membri della dimensione superiore 8. Quale è un limite pratico, l'allocatore di memoria non ritorno indirizzi allineati meglio 8. E double è brutalmente costoso se non è allineato correttamente e finisce a cavallo di una linea di cache. In caso contrario, mal di testa se si scrive codice SIMD, richiede un allineamento di 16 byte.

+0

Quindi, poiché l'allineamento predefinito è 8 in base a MSDN, l'ultimo snippet di codice nel mio OP è l'aspetto del riempimento di allineamento? In caso contrario, si prega di spiegare. –

+1

@Robert: il tuo ultimo codice è sbagliato. Sarà riempito come questo 'char foo; pad [3]; int bar; 'Perché' int' è il membro più grande della struttura. Dovresti leggere molto attentamente cosa ha detto Hans – Benjamin

3

Ciò non significa che ogni membro è allineato su un limite di 8 byte. Leggi un po 'più attentamente:

the smaller member type or n-byte boundaries 

La chiave qui è la prima parte- "tipo di membro più piccolo". Ciò significa che i membri con meno allineamento potrebbero essere allineati di meno, in modo efficace.

struct x { 
    char c; 
    int y; 
}; 
std::cout << sizeof(x); 
std::cout << "offsetof(x, c) = " << offsetof(x, c) << '\n'; 
std::cout << "offsetof(x, c) = " << offsetof(x, y) << '\n'; 

Questo produce 8, 0, 4- senso che, in realtà, il int è imbottita solo per un allineamento 4byte.

+1

L'ultima parte della tua risposta è errata. Rimuovere l'int dalla struttura e notare che sizeof() non restituisce 8. –

Problemi correlati