Integer promotion nedir? uint8_t ile yapılan işlemlerde beklenmedik sonuçlar neden oluşur? Örneklerle açıklayın.

Cevap

C'de int'ten küçük tipler (char, short, uint8_t, uint16_t, bit field) bir aritmetik ifadede kullanılmadan önce otomatik olarak `int`'e (değer sığmıyorsa unsigned int'e) yükseltilir. İşlem int genişliğinde yapılır ve sonuç ancak atamada daraltılır. Bu, 8/16-bit değişkenlerle çalışan gömülü kodda sık hataya yol açar.

Örnek 1: Bit tersleme

uint8_t a = 0xFF;
if (~a == 0x00)          /* YANLIŞ: ~a, int olarak 0xFFFFFF00 = -256 */
    puts("sifir");
if ((uint8_t)~a == 0x00) /* DOĞRU */
    puts("sifir");

Örnek 2: Taşma ara sonuçta olmaz

uint8_t x = 200, y = 100;
uint8_t z = x + y;            /* 300 -> 44 (atamada kesilir) */
if (x + y > 255) puts("tasti"); /* yazdırılır: işlem int'te 300 */

Örnek 3: Kaydırma

uint8_t r = 0x80;
uint8_t s = (r << 1) >> 1;   /* sonuç 0x80; ara değer int'te 0x100 */
uint8_t t = (uint8_t)(r << 1) >> 1;  /* sonuç 0x00 */

Örnek 4: Tehlikeli olan (undefined behavior)

uint16_t u = 0xFFFF;
uint32_t p = u * u;   /* 32-bit int'li sistemde: int * int = 4294836225 */
                      /* INT_MAX'ı aşar -> signed overflow -> UB */
uint32_t ok = (uint32_t)u * u;   /* doğru */

Burada operandlar unsigned olmasına rağmen int'e yükseltildikleri için çarpım signed olur. 16-bit int olan bir MCU'da (MSP430, AVR) aynı kod farklı davranır; bu da taşınabilirlik sorunudur.

Kurallar

  • Hesaplamanın sonucu dar tipe atanacaksa, ara ifadeyi de açıkça cast edin.
  • Çarpma ve kaydırmalarda en az bir operandı hedef genişliğe cast edin.
  • MISRA C'nin "essential type" kuralları (10.x) tam olarak bu tür hataları yakalamak için vardır.
  1. C dilinde volatile anahtar kelimesi ne işe yarar?OrtaC ProgramlamaEmbedded
  2. Bir yazmaçtaki belirli bir biti set, clear ve toggle eden C kodunu yazın.KolayC ProgramlamaEmbedded
  3. Stack ile heap arasındaki fark nedir? Gömülü sistemlerde dinamik bellek kullanımından neden kaçınılır?OrtaC ProgramlamaEmbedded
  4. Endianness nedir? Little-endian ile big-endian farkı nedir?KolayC ProgramlamaEmbedded
  5. Bit field nedir? Donanım register'larına erişimde bit field mi yoksa bit maskesi mi kullanılmalı?OrtaC ProgramlamaEmbedded
  6. Fonksiyon pointer'ları ve callback tabloları gömülü sistemlerde nasıl kullanılır? Bir state machine örneği verin.OrtaC ProgramlamaEmbedded

Bu konuda başka bir soru biliyor musun?

Mülakatta karşılaştığın soruları ekle, onaylandıktan sonra yayına alınsın.

Soru ekle