Undefined behavior (tanımsız davranış) nedir? Gömülü C kodunda sık görülen UB örnekleri nelerdir?
Cevap
Undefined behavior, C standardının hiçbir davranış garanti etmediği durumlardır. Derleyici "bu asla olmaz" varsayımıyla optimizasyon yapabilir; kod debug build'de çalışıp -O2 ile bozulabilir ya da farklı bir derleyicide farklı davranabilir.
Sık görülen UB örnekleri
int i = 1;
i = i++ + 1; /* aynı nesneyi sequence point olmadan iki kez değiştirmek */
int32_t x = INT32_MAX;
x = x + 1; /* signed overflow (unsigned overflow ise tanımlıdır: sarar) */
uint32_t v = 1;
v = v << 32; /* kaydırma miktarı >= tip genişliği */
int s = 1 << 31; /* 32-bit int'te sonuç temsil edilemez: UB */
int arr[4];
arr[4] = 0; /* dizi sınırı dışı yazma */
int *p = NULL;
*p = 5; /* NULL dereference */
int y;
printf("%d", y); /* başlatılmamış otomatik değişken okumak */
float f = 1.0f;
uint32_t bits = *(uint32_t *)&f; /* strict aliasing ihlali */Derleyicinin UB'yi nasıl "kullandığı"
int check(int a)
{
if (a + 1 < a) /* signed overflow olamaz varsayımıyla */
return 1; /* bu dal tamamen silinebilir */
return 0;
}Doğru alternatifler
- Kaydırma için
1u << 31, tip genişliğinden büyük kaydırma yapmayın. - Tip dönüşümü (type punning) için
memcpy(&bits, &f, sizeof bits);kullanın; derleyici bunu tek bir talimata indirir. - Taşma kontrolünü işlemden önce yapın:
if (a > INT_MAX - b).
Tespit araçları
-Wall -Wextra -Wshift-overflow -Wstrict-aliasing- Host üzerinde birim testleri
-fsanitize=undefined,addressile çalıştırmak - Statik analiz: cppcheck, clang-tidy, MISRA denetleyicileri
Ayrıca implementation-defined (ör. signed sayının sağa kaydırılması, char'ın işaretli olup olmadığı) ve unspecified (fonksiyon argümanlarının değerlendirme sırası) davranışları UB'den ayırmayı bilin.
İ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.