2016-01-06 18 views
8

Aşağıdaki kodu 32 bit x86 Linux için çalıştırırken beklenmedik sonuçlar alıyorum (derleyici bayrakları: g ++ -std = C++ 14 -m32). Gcc ve clang'ı denedim.32 bit platformlardaki yapılarda alignas

#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; 
} 

çıktısı: Burada neler oluyor

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

? Neden farklı boyutlarda S1 ve S2? Anladığım kadarıyla, 64 bit tamsayı değerleri 32 bit x86 makinelerinde 32 bit olarak hizalanır. Bu, S1 boyutunun neden 12 bayt olduğunu açıklıyor. Ama bu neden S2 için geçerli değil?

+0

Muhtemelen karakter dizisi için a satır dizilimi a önbelleği S2 16 bayt yapmak için dizi için bir adet 4 baytlık blok içeriyor? Muhtemelen ilgili: http://stackoverflow.com/questions/17091382/memory-alignment-how-to-use-alignof-alignas – dfri

+2

Bu bir cevap değil, ilerlemedir. alignas (uint64_t) ', alignas (alignof (uint64_t))' ile aynıdır. Eğer cout << alignof (uint64_t) << endl; 'örneğine eklerseniz 8 bir çıktı elde edersiniz (en azından gcc). Yani soru şu olmalı: 'neden gcc, alignof (uint64_t)' nin söz konusu platformda 4 olduğunda 8 olduğunu düşünüyor. Not: 4 olması gerekir çünkü sizeof (S1) 12'dir. – Persixty

+0

Boyuttaki farkın 'char [8] 'kullandığınız gerçeğiyle ilgili olup olmadığını görmek için, lütfen' S2 'de değiştirebilir misiniz? : alignas (uint64_t) char a [8]; '** başka bir 64 bit türü **, örneğin bir" çift "gibi mi? – arainone

cevap

4

alignof anahtar sözcüğü, bir türün tam bir nesne olarak hizalanmasını ölçer; yani, tek bir nesne veya dizi elemanı olarak tahsis edildiğinde. Bu, bu türün bir alt nesne olarak hizalama gereksinimleriyle aynı olmak zorunda değildir; Are members of a POD-struct or standard layout type guaranteed to be aligned according to their alignment requirements?

Bir yapının içindeki 64 bitlik bir tamsayı hizalama, 4 baytta x386 ABI tarafından zorunlu tutulur; gcc, diğer nesne dosyaları ve programlarla ikili uyumluluğu bozacağından bunu değiştirmek için özgür değildir. Ancak, tam nesneyi 64 bit tam sayıları 8 bayt olarak hizalayabilir, böylelikle ABI'yi etkilemez ve belleğe daha verimli erişim sağlar.

İlgili konular