Kasıtlı olmayan bir C kodu dışında bir dizinin sonuna geçmiş erişen kod üreten bir DSP çip için bir derleyici ile çalışıyorum!
Bunun nedeni, döngülerin bir yinelemenin sonu bir sonraki yineleme için bazı verileri önceden alacak şekilde yapılandırılmış olmasıdır. Bu nedenle, son yinelemenin sonunda önceden getirilmiş olan veri asla kullanılmaz.
Bu şekilde C kodu yazmak, tanımlanmamış davranışı gerektirir, ancak bu yalnızca standart bir belgeden maksimum taşınabilirlikle ilgilenen bir formalitedir.
Daha sık olmamakla birlikte, sınırların dışına erişen bir program akıllıca optimize edilmez. Sadece adamcağız. Kod bir miktar çöp değeri getirir ve yukarıda bahsedilen derleyicinin optimize edilmiş döngülerinin aksine, kod daha sonra sonraki hesaplamalarda değeri kullanır , böylece imi bozar.
Bu gibi hataları yakalamaya değer ve bu yüzden sadece bu nedenle bile davranışı tanımsız hale getirmeye değer: böylece çalışma zamanı "main.c satır 42'de dizi taşması" gibi bir tanılama mesajı üretebilir.
Sanal belleğe sahip sistemlerde, izleyen adres sanal belleğin eşlenmemiş alanında olacak şekilde bir dizi atanabilir. Erişim daha sonra programı bombalayacaktır.
Bir kenara, C'de bir dizinin sonundan bir işaretçi oluşturmamıza izin verildiğini unutmayın. Ve bu işaretçi, bir dizinin iç kısmıyla herhangi bir işaretçiden daha büyük karşılaştırmak zorundadır. Bu, bir C uygulamasının bir diziyi belleğin sonuna yerleştiremeyeceği, bir artı adresin etrafa sarılacağı ve dizideki diğer adreslerden daha küçük görüneceği anlamına gelir.
Bununla birlikte, başlatılmamış veya sınır dışı değerlere erişim, maksimum düzeyde taşınabilir olmasa bile, bazen geçerli bir optimizasyon tekniğidir. Bu nedenle, Valgrind aracının bu erişim gerçekleştiğinde başlatılmamış verilere erişimi raporlamamasının nedeni, ancak değer daha sonra programın sonucunu etkileyebilecek bir şekilde kullanıldığında. "Xxx'de koşullu dal: nnn başlatılmamış değere bağlıdır" gibi bir tanı alırsınız ve kökenini izlemek bazen zor olabilir. Bu tür tüm erişimler hemen yakalanırsa, derleyici için optimize edilmiş kodun yanı sıra elle optimize edilmiş koddan kaynaklanan çok sayıda yanlış pozitif olurdu.
Bundan bahsetmişken, Linux'a taşındığında ve Valgrind altında çalıştırıldığında bu hataları veren bir satıcıdan bazı codec ile çalışıyordum. Ancak satıcı beni sadece birkaç kişinin bitinkullanılan değerin büyük kısmı başlatılmamış bellekten geldi ve bu bitler mantık tarafından dikkatle önlendi. Sadece değerin iyi bitleri kullanılıyordu ve Valgrind bireysel biti takip etme yeteneğine sahip değildi. Başlatılmamış materyal, kodlanmış bir bit veri akışının sonunu geçen bir kelimeyi okumaktan geldi, ancak kod akışta kaç bit olduğunu biliyor ve gerçekte olduğundan daha fazla bit kullanmayacak. Bit akışı dizisinin sonunun ötesindeki erişim DSP mimarisine zarar vermediğinden (diziden sonra sanal bellek yoktur, bellek eşlemeli bağlantı noktası yoktur ve adres sarılmaz) geçerli bir optimizasyon tekniğidir.
"Tanımlanmamış davranış" gerçekten fazla bir şey ifade etmez, çünkü ISO C'ye göre, basitçe C standardında tanımlı olmayan bir başlık eklemek veya programın kendisinde veya C standardında tanımlı olmayan bir fonksiyon çağırmak tanımsız örneklerdir davranışı. Tanımsız davranış "gezegendeki hiç kimse tarafından tanımlanmamış" anlamına gelmez "sadece" ISO C standardı tarafından tanımlanmamıştır. Ama tabii ki, bazen tanımsız davranış gerçekten edilir kesinlikle herkes tarafından tanımlanmamış.