Derleyiciler hataları ve uyarıları nasıl bildirmelidir?


11

Yakın gelecekte bir derleyici yazmayı planlamıyorum; yine de, derleyici teknolojileriyle ve bunun nasıl daha iyi hale getirilebileceğiyle oldukça ilgileniyorum.

Derlenmiş dillerden başlayarak, çoğu derleyicinin iki hata düzeyi vardır: uyarılar ve hatalar, ilki çoğu zaman düzeltmeniz gereken ölümcül olmayan şeyler ve çoğu zaman makine- (veya bayt-) üretmenin imkansız olduğunu gösteren hatalar kodunu girin.

Yine de, bu oldukça zayıf bir tanım. Java gibi bazı dillerde, @SuppressWarningyönergeleri kullanmadan bazı uyarıların kaldırılması imkansızdır . Ayrıca, Java bazı ölümcül olmayan sorunları hata olarak ele alır (örneğin, Java'daki erişilemeyen kod bilmek istediğim bir nedenden dolayı bir hatayı tetikler).

C # aynı sorunlara sahip değil, ama birkaç tane var. Derleme birkaç geçişte gerçekleşir ve başarısız bir geçiş daha sonraki geçişlerin yürütülmesini engelleyecektir. Bu nedenle, derlemeniz başarısız olduğunda aldığınız hata sayısı genellikle kaba bir şekilde küçümsenir. Bir koşuda iki hatanız olduğunu söyleyebilir, ancak bir kez düzelttikten sonra 26 yenisi alırsınız.

C ve C ++ 'a kazmak, Java ve C #' ın derleme tanı zayıflıklarında kötü bir kombinasyon gösterir (ancak Java ve C # 'ın her birinin yarısı ile yoluna gittiğini söylemek daha doğru olabilir). Bazı uyarılar gerçekten hata olmalıdır (örneğin tüm kod yolları bir değer döndürmediğinde) ve yine de uyarılardır, çünkü standart yazdıklarında derleyici teknolojisinin bu türden yapmak için yeterince iyi olmadığını düşünüyorum. zorunlu kontroller. Aynı şekilde, derleyiciler genellikle standardın söylediklerinden daha fazlasını kontrol eder, ancak yine de ek bulgular için "standart" uyarı hatası seviyesini kullanır. Çoğu zaman, derleyiciler bulabildikleri tüm hataları hemen rapor etmez; hepsinden kurtulmak için birkaç derleme gerekebilir. C ++ derleyicilerinin tükürmeyi sevdiği şifreli hatalardan bahsetmiyorum,

Şimdi, derleyiciler uyarı yayınladığında birçok derleme sisteminin arızaları bildirecek şekilde yapılandırılabildiğini ekleyerek, sadece garip bir karışım elde ediyoruz: tüm hatalar ölümcül değil, bazı uyarılar; tüm uyarılara hak edilmez, ancak bazıları varoluşlarından daha fazla söz edilmeden açıkça bastırılır; ve bazen tüm uyarılar hata olur.

Derlenmemiş diller hala berbat hata raporlama payına sahiptir. Python'daki yazım hataları kod çalıştırılıncaya kadar rapor edilmez ve komut dosyası bir tanıştıktan sonra yürütmeyi durduracağından, bir kerede birden fazla hatayı asla tekmeleyemezsiniz.

PHP, kendi tarafında, az çok önemli hata seviyeleri ve istisnalara sahiptir. Ayrıştırma hataları birer birer rapor edilir, uyarılar genellikle komut dosyanızı iptal etmeleri çok kötüdür (ancak varsayılan olarak değil), bildirimler gerçekten ciddi mantık sorunlarını gösterir, bazı hatalar komut dosyanızı durduracak kadar kötü değildir, ancak yine de PHP ile her zamanki gibi, orada gerçekten garip şeyler var (neden gerçekten ölümcül olmayan ölümcül hatalar için bir hata seviyesine ihtiyacımız var?, E_RECOVERABLE_E_ERRORSeninle konuşuyorum).

Bana öyle geliyor ki derleyebileceğim her derleyici hatası raporlaması uygulaması bozuldu. Bu iyi bir utançtır, çünkü tüm iyi programcıların hatalarla doğru bir şekilde başa çıkmanın ne kadar önemli olduğu konusunda ısrar ettikleri ve yine de kendi araçlarını alamadıkları.

Derleyici hatalarını bildirmenin doğru yolu ne olmalı?


-1: "Derlenmemiş diller hala berbat hata bildirimi payına sahiptir" Öznel ve tartışmacı. Gerçekten yararsızdır. Bu bir soru mu yoksa şikayet mi?
S.Lott

2
@ S.Lott Burada biraz kenarda olduğunuzu düşünüyorum. Derlenmiş dillerde çok daha zor olduğumu fark ettim ve bu sizi rahatsız etmiyor gibi görünüyor.
Ocak'ta

@zneak: Diğer ifadeler olgusal olmaya daha yakın ve ayrıştırılması daha zor. Bu ifadenin en kolay şekilde öznel ve tartışmacı olduğu gösterilmiştir.
S.Lott

1
@ S.Lott Python'un her seferinde bir hata gösterdiğini belirtmek yanlış mıyım?
Ocak'ta

1
@ S.Lott O zaman işler değişmiş olmalı, çünkü en son denediğimde, herhangi bir sözdizimi hatası Python'un "derlemeye" çalışmayı durdurmasına neden olacak ve bir ad hatası bir istisna atacak ve işlevin geri kalanını kontrol etmeyecekti (bu ayrıldı) test edilebilir birim başına bir hata bildirmek için yer). Sübjektif ve tartışmacı ifadem, bir gerçek olduğuna inandığım şeye bir girişti, ancak artık doğru değilse, gidip sorumu düzenleyeceğim. Şimdi nasıl çalışıyor?
Ocak'ta

Yanıtlar:


6

Sorunuz aslında derleyici hatalarını nasıl raporladığımızla ilgili değil - sorunların sınıflandırılması ve bunlar hakkında ne yapılması gerektiği ile ilgili.

Şu an için uyarı / hata ikileminin doğru olduğunu varsayarsak, bunun üzerine ne kadar iyi inşa edebileceğimizi görelim. Bazı fikirler:

  1. Farklı uyarı seviyeleri. Birçok derleyici bunu uygular (örneğin GCC, tam olarak ne hakkında uyarı vereceğini yapılandırmak için çok sayıda anahtara sahiptir), ancak çalışması gerekir - örneğin, bildirilen bir uyarının şiddetini ve "uyarıları ayarlama yeteneğini" bildirme yalnızca belirtilen önem derecesinin üzerindeki uyarılar için hatalardır.

  2. Hataların ve uyarıların aklı başında sınıflandırılması. Bir hata sadece kod spesifikasyonu karşılamıyorsa ve bu nedenle derlenemezse rapor edilmelidir. Ulaşılamayan ifadeler, muhtemelen bir kodlama hatası olsa da, bir hata değil, bir uyarı olmalıdır - kod hala "geçerli" dir ve erişilemeyen kodla derlemek isteyebileceğiniz meşru örnekler vardır (örneğin, hata ayıklama için hızlı değişiklikler) .

Şimdi sizinle aynı fikirde olmadığım şeyler:

  1. Her sorunu bildirmek için ekstra çaba sarf etmek. Bir hata varsa, bu derlemeyi bozar. Yapı bozuk. Bu hata düzeltilene kadar derleme çalışmaz. Bu nedenle, kodla "yanlış" olan her şeyi tanımlamaya çalışmak için "devam etmek" yerine bu hatayı hemen bildirmek daha iyidir. Özellikle de bunların çoğuna muhtemelen ilk hata nedeniyse.

  2. Hatayla ilgili bir uyarıya ilişkin özel örneğiniz. Evet, muhtemelen bir programcı hatasıdır. Hayır, yapıyı bozmamalıdır. Eğer işleve girdi her zaman bir değer döndürecek şekilde olduğunu biliyorum, ben bu ekstra kontroller eklemek zorunda kalmadan inşa çalıştırmak ve bazı testler yapmak mümkün olmalıdır. Evet, bir uyarı olmalı. Ve lanet olası bir yüksek ciddiyette. Ancak, hatalarla ilgili uyarılarla derlenmedikçe, yapıyı kendi başına kırmamalıdır.

Düşünceler?


Katılıyorum (duh) noktalar hariç, sana katılıyorum, bu yüzden benden +1. Tanımlanmamış davranış durumunda gerçekten düştüğünüzde ne kadar kötü olduğunu düşünerek, her kod yolunu bir değer döndürmek veya programınızı iptal etmek için yeterince kolay olduğunu düşünüyorum.
zneak

7

Ortaya koyduğunuz bir sorun, hataların eksik raporlanmasıydı - örneğin, 2 hata bildirmek ve bunları düzelttiğinizde, daha fazlasını elde edersiniz.

Bu (büyük ölçüde) derleyici yazarının bir uzlaşmasıdır. Derleyici ne yanlış başlamak için yaptığınız ne hata bağlı olarak, çok kolay yapmak kötü yeterince gerçekle pek ilgisi var rapor hatalarına başladığını var. Örneğin, itn x;bunun yerine bir şeyin olduğu basit bir yazım hatasını düşünün int x;. Bir şey ifade eden başka bir şey yapmadıysanız itn, bu bir hata olarak rapor edilecektir. Bu gittikçe iyi, ama şimdi ne olacağını düşünün - derleyici değişken olarak kullanmaya çalışan birçok koda bakar x. A) durmalı ve bunu düzeltmenize izin vermeli mi, yoksa B) error: "x": undeclared identifierbu siparişle ilgili 2000 hata veya başka bir şey mi yazdı ? Başka bir olasılık düşünün:

int main()[

Bu başka bir oldukça açık yazım hatası - açıkçası bir {yerine bir [. Derleyici bu bölümü kolayca söyleyebilir - ancak böyle bir şey x=1;söyleme gibi bir hatayı bildirmeye devam etmeli error: statement only allowed inside a functionmi?

Bunların bile oldukça önemsiz problemler olduğunu unutmayın - çok daha kötü olanları bulmak kolaydır (özellikle, çoğumuzun bildiği gibi, C ++ şablonlarına girdiğinizde). Sonuç olarak, derleyici yazarı genellikle yanlış hataların bildirilmesi (yani, bir şey iyi olsa bile bir hata olarak bildirilmesi) ile gerçek hataları bildirememe arasında uzlaşmaya çalışmakla sıkışmış durumdadır. Her iki yönde de çok fazla yanlış gitmekten kaçınmak için en çok takip edilen bazı kurallar vardır, ancak neredeyse hiçbiri mükemmelliğe yakın bir yerde değildir.

Bahsettiğiniz bir diğer problem Java ve @SupressWarning. Bu yukarıdakilerden oldukça farklıdır - düzeltmek oldukça önemsiz olacaktır. Düzeltilmemesinin tek nedeni, Java'nın temel "karakteri" ile uyuşmamasıdır - yani, onların görüşüne göre, "bu bir hata değil, bir özelliktir." Genellikle bir şaka olmasına rağmen, bu durumda ilgili insanlar o kadar yanlış yönlendirilirler ki gerçekten doğru olduğuna inanırlar.

C ve C ++ 'da bir değer döndürmeyen kod yolları ile bahsettiğiniz sorun, ilkel derleyicilere izin vermek değildir. Kimsenin düzeltmek, dokunmak ve hatta okumak istemediği on yıllar boyunca mevcut kodlara izin vermek . Eski ve çirkin ama işe yarıyor ve kimse çalışmaya devam etmesi için başka bir şey istemiyor. Daha iyisi ya da daha kötüsü, dil komiteleri bu geriye dönük uyumluluğu sürdürmekle büyük ölçüde sıkışmıştır, bu yüzden kimsenin gerçekten sevmediği şeylere izin vermeye devam ederler - ancak bazı insanlar (en azından düşündükleri).


3
Birçok kişiye neden olan erken hatalar hakkındaki görüşünüze ek olarak, daha sonraki geçişlerin genellikle daha erken geçişlerin başarıyla tamamlanmasını gerektirecek şekilde oluşturulduğu gerçeği de vardır. Örneğin, C # derleyicisindeki erken geçişlerden biri, devralma grafiğinde döngü olmadığından emin olmak için kontrol eder - A'dan devralınan B'den A devralınması yoktur. Devam etmek ve bir liste oluşturmak istiyorsanız bundan sonraki tüm hatalar için, daha sonraki her geçiş, döngülerle başa çıkabilmelidir - bu da "iyi" derlemelerde bile önemli ölçüde yavaşlar.
Anon.

@Anon. Java derleyicisi, erken geçişlerde hayatta kalmak için çok daha iyi çaba harcıyor ve bunu daha yavaş bulmuyorum. Benim için ne kadar hızlı cscvazgeçmek biraz can sıkıcı .
Ocak'ta

@zneak: Jerry'nin dediği gibi, derleyicilerin geliştiricileri açısından bir uzlaşma. İyi hata teşhisi yazmak aslında çok zor bir sorundur ( gerçekten ne kadar uzağa gidebileceğinizi gösteren bir örnek için clang'a bakın). C # derleyicisinin aşamaları ve geçişleri hakkında iyi bir tartışma için buraya bakın .
Dean Harding
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.