C dilinde yapılar (struct) diğer yapıların ve farklı veri türlerinin içerebilir. Ancak yapının içindeki alanların konumu, onun boyutunu ve hizalamasını etkileyebilir. Derleyici, en büyük alana göre hizalamayı (alignment) sağlamak için ek baytlar (padding) ekler. Bu, performans ve işlemcinin doğru çalışması için önemlidir.
Eğer bir yapı, iç içe yapılar içeriyorsa, hizalama, özyinelemeli olarak uygulanır:
#pragma pack veya GCC/Clang'da __attribute__((packed)) kullanarak).Örnek:
#include <stdio.h> struct Inner { char c; int x; }; struct Outer { char a; struct Inner b; short s; }; int main() { printf("sizeof(struct Inner) = %zu\n", sizeof(struct Inner)); printf("sizeof(struct Outer) = %zu\n", sizeof(struct Outer)); return 0; } // sizeof(struct Inner) = 8 (64 bit), sizeof(struct Outer) = 16 veya 24
Pack ve packed kullanımı, hizalamayı göz ardı ederek boyutu azaltabilir, ancak bu bazı platformlarda (ARM, DSP vb.) performansı azaltabilir veya hatalara neden olabilir.
Soru: Aynı yapının tüm platformlarda aynı boyutta olmasını garanti edebilir miyiz?
Cevap: Hayır! C standartı, aynı hizalamayı, bayt sırasını (endian) garanti etmez ve alanlar arasında ve yapının sonunda "padding" ekleyebilir. Yapılar arasında ikili uyumluluk için hizalamayı elle yönetmeyi kullanın ve her hedef platformda sizeof değerini her zaman açıkça test edin.
Örnek:
struct Data { char c; int x; }; // sizeof(Data) genellikle 8 64 bit üzerinde, 5 veya 8 32 bit üzerinde
Tarih
Mikrokontrolör (ARM) ve PC arasında ikili protokol aracılığıyla yapı değişimi sırasında ARM'dan gelen veriler, farklı padding ve bayt sırası nedeniyle PC'de beklenenlerle eşleşmedi. Bu, yanlış parametrelerin kodlanmasına ve cihaz kontrolünde fiziksel hatalara yol açtı.
Tarih
Ağ protokolünde veri gönderimini hızlandırmak için packed yapılar eklendi, ancak hizalama olmayan bir platformda belirli alanların çalışmadığı göz ardı edildi (işlemci uyumsuz erişimi desteklemiyordu). Sonuç: ağ paketleri ile çalışırken donanım istisnaları.
Tarih
Sunucu, yapı kayıtlarından oluşan harici bir dosyayla çalışıyordu. Derleyici güncellendikten sonra yapının boyutu değişti (farklı hizalama). Dosyadaki eski veriler doğru bir şekilde okunamadı, bazı bilgiler "bozuldu".