2016-01-06 16 views
8

Ottengo risultati imprevisti quando si esegue il seguente codice per 32 bit x86 linux (flag del compilatore: g ++ -std = C++ 14 -m32). Ho provato gcc e clang.allineamenti nelle strutture su piattaforme a 32 bit

#include <iostream> 
using namespace std; 

struct S1 
{ 
    uint64_t a; 
    uint32_t b; 
}; 

struct S2 
{ 
    alignas(uint64_t) char a[8]; 
    uint32_t b; 
}; 

int main() 
{ 
    cout << "sizeof(S1)=" << sizeof(S1) << endl; 
    cout << "sizeof(S2)=" << sizeof(S2) << endl; 
} 

L'output è:

sizeof(S1)=12 
sizeof(S2)=16 

Cosa sta succedendo qui? Perché S1 e S2 hanno dimensioni diverse? A quanto ho capito, i valori interi a 64 bit sono allineati a 32 bit su macchine x86 a 32 bit. Questo spiega perché la dimensione di S1 ​​è di 12 byte. Ma perché questo non si applica a S2?

+0

Forse l'allineamento delle righe nella cache per l'array di caratteri 'a' include un blocco di 4 byte in più per l'array per creare S2 16 byte? Forse correlato: http://stackoverflow.com/questions/17091382/memory-alignment-how-to-use-alignof-alignas – dfri

+2

Questa non è una risposta, ma progresso. 'alignas (uint64_t)' è definito come 'alignas (alignof (uint64_t))'. Se aggiungi 'cout << alignof (uint64_t) << endl;' all'esempio otterrai un risultato di 8 (gcc almeno). Quindi la domanda dovrebbe essere "perché gcc pensa che alignof (uint64_t) è 8 quando è 4 sulla piattaforma in questione. NB: Deve essere 4 perché sizeof (S1) è 12. – Persixty

+0

Per vedere se la differenza di dimensioni può essere correlata al fatto che stai usando un 'char [8]', Potresti sostituire, in 'S2' : 'alignas (uint64_t) char a [8];' con ** un altro tipo a 64 bit **, come ad esempio un 'double'? – arainone

risposta

4

La parola chiave alignof misura l'allineamento di un tipo come un oggetto completo; cioè quando è assegnato come un singolo oggetto o elemento di matrice. Questo non è necessariamente uguale ai requisiti di allineamento di quel tipo come subobject; Are members of a POD-struct or standard layout type guaranteed to be aligned according to their alignment requirements?

L'allineamento di un numero intero a 64 bit all'interno di una struttura è richiesto dall'ABI x386 a 4 byte; gcc non è libero di cambiare questo, in quanto romperebbe la compatibilità binaria con altri file e programmi di oggetti. Tuttavia, può allineare interi interi a 64 bit di oggetti completi a 8 byte, in quanto ciò non influisce sull'ABI e rende più efficiente l'accesso alla memoria.