Struct padding ve alignment nedir? __attribute__((packed)) ne zaman kullanılmalı, riskleri nelerdir?
Cevap
İşlemciler veriye doğal hizalamasında (4 byte'lık uint32_t için 4'ün katı adres) en verimli erişir. Derleyici bu yüzden struct alanları arasına padding byte'ları ekler. Struct'ın toplam boyutu da en büyük üyenin hizalamasının katına yuvarlanır.
struct A { /* offset */
uint8_t a; /* 0, sonra 3 byte padding */
uint32_t b; /* 4 */
uint16_t c; /* 8, sonra 2 byte padding */
}; /* sizeof = 12 */
struct B { /* aynı alanlar, büyükten küçüğe */
uint32_t b; /* 0 */
uint16_t c; /* 4 */
uint8_t a; /* 6, sonra 1 byte padding */
}; /* sizeof = 8 */Alanları büyükten küçüğe sıralamak padding'i en aza indirir ve RAM kazandırır.
packed
typedef struct __attribute__((packed)) {
uint8_t cmd;
uint32_t value;
uint16_t crc;
} frame_t; /* sizeof = 7 */Kullanım yerleri: haberleşme protokol çerçeveleri, dosya formatları, donanıma birebir uyması gereken yapılar.
Riskler
- Hizalanmamış erişim: Cortex-M0/M0+ hizalanmamış
LDRile HardFault verir. Cortex-M3/M4 destekler ama daha yavaştır. Derleyici packed alana doğrudan erişirken güvenli kod üretir, ama alanın adresi biruint32_t *pointer'a alınırsa bu garanti kaybolur. - Performans: Byte byte okuma kodu üretilir.
- Taşınabilirlik: Endianness hâlâ çözülmez; farklı mimaride byte sırası değişir.
Daha güvenli alternatif
Protokol verisini struct'a cast etmek yerine açıkça serialize etmek:
buf[0] = f->cmd;
buf[1] = (uint8_t)(f->value);
buf[2] = (uint8_t)(f->value >> 8);
buf[3] = (uint8_t)(f->value >> 16);
buf[4] = (uint8_t)(f->value >> 24); /* little-endian, açık ve taşınabilir */Boyutu derleme zamanında doğrulamak için: _Static_assert(sizeof(frame_t) == 7, "frame size");
İlgili C Programlama soruları
- C dilinde volatile anahtar kelimesi ne işe yarar?
- Bir yazmaçtaki belirli bir biti set, clear ve toggle eden C kodunu yazın.
- Stack ile heap arasındaki fark nedir? Gömülü sistemlerde dinamik bellek kullanımından neden kaçınılır?
- Endianness nedir? Little-endian ile big-endian farkı nedir?
- Bit field nedir? Donanım register'larına erişimde bit field mi yoksa bit maskesi mi kullanılmalı?
- Fonksiyon pointer'ları ve callback tabloları gömülü sistemlerde nasıl kullanılır? Bir state machine örneği verin.
Bu konuda başka bir soru biliyor musun?
Mülakatta karşılaştığın soruları ekle, onaylandıktan sonra yayına alınsın.