it-swarm.asia

Neden derleyiciler bu kadar güvenilir?

Derleyicileri her gün doğrulukları verilmiş gibi kullanırız, ancak derleyiciler de programlardır ve potansiyel olarak hata içerebilir. Her zaman bu yanılmaz sağlamlığı merak ettim. Hiç derleyicinin kendisinde bir hatayla karşılaştınız mı? Nedir ve sorunun derleyicinin kendisinde olduğunu nasıl anladınız?

... ve nasıl do derleyicileri bu kadar güvenilir yapıyorlar?

67
EpsilonVector

Zaman içinde binlerce hatta milyonlarca geliştiricinin kullanımı ile kapsamlı bir şekilde test edilirler.

Ayrıca, çözülecek problem iyi tanımlanmıştır (çok detaylı bir teknik şartname ile). Ve görevin doğası kolayca birim/sistem testlerine uygundur. Yani temel olarak metin girişini başka bir iyi tanımlanmış formatta (bir çeşit bayt kodu veya makine kodu) çıktı almak için çok özel bir formatta çevirmektedir. Bu nedenle test senaryoları oluşturmak ve doğrulamak kolaydır.

Dahası, genellikle hataların da çoğaltılması kolaydır: tam platform ve derleyici sürüm bilgilerinin yanı sıra, genellikle ihtiyacınız olan tek şey bir giriş kodu parçasıdır. Derleyici kullanıcıların (geliştiricilerin kendileri) herhangi bir ortalama bilgisayar kullanıcısından çok daha kesin ve ayrıntılı hata raporları verme eğiliminde olduklarından bahsetmiyorum :-)

101
Péter Török

Şimdiye kadarki tüm harika cevaplara ek olarak:

"Gözlemci önyargınız" var. Hataları gözlemlemezsiniz ve bu nedenle herhangi bir şey olmadığını varsayarsınız.

Eskiden senin gibi düşünürdüm. Sonra profesyonel olarak derleyiciler yazmaya başladım ve size söyleyeyim, içinde çok fazla hata var!

Hataları görmüyorsunuz çünkü insanların yazdığı kodun geri kalanının% 99,999'u gibi bir kod yazıyorsunuz. Muhtemelen, normal iş sorunlarını çözen normal bir geliştiricisiniz, çünkü yöntemleri çağıran ve döngüler çalıştıran ve süslü veya garip bir şey yapmayan mükemmel normal, basit, açıkça doğru kod yazıyorsunuz.

Herhangi bir derleyici hatası görmüyorsunuz çünkü derleyici hataları analiz edilmesi kolay normal kod senaryolarında değil; hatalar, yazmadığınız garip kodların analizinde.

Diğer yandan karşıt gözlemci yanlılığım var. Her gün çılgın bir kod görüyorum ve bu yüzden bana göre derleyiciler hatalarla doludur.

Herhangi bir dilin dil spesifikasyonuna oturduysanız ve bu dil için herhangi bir derleyici uygulaması aldıysanız ve derleyicinin spesifikasyonu tam olarak uygulayıp uygulamadığını belirlemek için çok çalıştıysanız, belirsiz köşe vakalarına odaklanarak, yakında bulacaksınız derleyici hataları oldukça sık. Size bir örnek vereyim, işte beş dakika önce bulduğum bir C # derleyici hatası.

static void N(ref int x){}
...
N(ref 123);

Derleyici üç hata verir.

  • Bir ref veya out argümanı atanabilir bir değişken olmalıdır.
  • N (ref int x) için en iyi eşleşme geçersiz argümanlara sahip.
  • 1 numaralı argümanda eksik "ref".

Açıkçası ilk hata mesajı doğrudur ve üçüncüsü bir hatadır. Hata üretme algoritması ilk argümanın neden geçersiz olduğunu anlamaya çalışıyor, ona bakıyor, sabit olduğunu görüyor ve "ref" olarak işaretlenip işaretlenmediğini kontrol etmek için kaynak koduna geri dönmüyor; aksine, hiç kimsenin bir sabiti ref olarak işaretleyecek kadar aptal olmayacağını varsayar ve ref'nin eksik olması gerektiğine karar verir.

Doğru üçüncü hata mesajının ne olduğu net değil, ama bu değil. Aslında, ikinci hata mesajının da doğru olup olmadığı açık değildir. Aşırı yük çözünürlüğü başarısız mı yoksa "ref 123" doğru tipte bir ref argümanı olarak mı ele alınmalı? Şimdi biraz düşünmem ve triyaj ekibi ile konuşmam gerek, böylece doğru davranışın ne olduğunu belirleyelim.

Bu hatayı hiç görmediniz çünkü muhtemelen 123'ü ref ile geçmeye çalışacak kadar aptalca bir şey yapmazsınız. Ve eğer yaptıysanız, üçüncü hata mesajının saçma olduğunu fark etmezsiniz, çünkü ilk mesaj doğru ve sorunu teşhis etmek için yeterlidir. Ama böyle şeyler yapmaya çalışıyorum, çünkü derleyiciyi kırmak için deniyorum. Eğer denediyseniz, hataları da görürsünüz.

66
Eric Lippert

Benimle dalga mı geçiyorsun? Derleyiciler de hata var, gerçekten yükler.

GCC muhtemelen gezegendeki en ünlü açık kaynak derleyicilerinden biridir ve hata veritabanına bir göz atın: http://gcc.gnu.org/bugzilla/buglist.cgi?product=gcc&component=c%2B% 2B ve çözümü = ---

GCC 3.2 ile GCC 3.2.3 arasında kaç hatanın giderildiğine bir göz atın: http://gcc.gnu.org/gcc-3.2/changes.html

Visual C++ gibi diğerlerine gelince, başlamak bile istemiyorum.

Derleyicileri nasıl güvenilir yaparsınız? Başlangıç ​​için yükler ve birim testler yükler. Ve tüm gezegen onları kullanıyor, bu yüzden testçilerin dehşeti yok.

Cidden, inanmak istediğim derleyici geliştiricileri üstün programcılardır ve yanılmaz olmasalar da oldukça yumruk atıyorlar.

54
Fanatic23

Günümde iki ya da üç karşılaştım. Birini tespit etmenin tek gerçek yolu Montaj koduna bakmaktır.

Her ne kadar derleyiciler diğer posterlerin işaret ettiği nedenlerden dolayı oldukça güvenilir olsa da, derleyici güvenilirliğinin genellikle kendi kendini gerçekleştiren bir değerlendirme olduğunu düşünüyorum. Programcılar derleyiciyi standart olarak görme eğilimindedir. Bir şeyler ters gittiğinde, hatanızı varsayarsınız (çünkü zamanın% 99,999'u) ve kodunuzu diğer yol yerine derleyici sorunu etrafında çalışacak şekilde değiştirin. Örneğin, yüksek bir optimizasyon ayarının altında kod çökmesi kesinlikle bir derleyici hatasıdır, ancak çoğu insan bunu biraz daha düşük bir değere ayarlar ve hatayı bildirmeden devam eder.

21
Karl Bielefeldt

Derleyiciler, doğruluklarına yol açan çeşitli özelliklere sahiptir:

  • Alan çok iyi bilinir ve araştırılır. Sorun iyi tanımlanmış ve sunulan çözümler iyi tanımlanmış.
  • Derleyicilerin doğru çalıştığını kanıtlamak için otomatik test yeterlidir
  • Derleyiciler, diğer programların çoğundan daha fazla hata alanını kapsayacak şekilde zaman içinde biriken çok kapsamlı, genellikle genel, otomatik ve birim testlere sahiptir.
  • Derleyiciler, sonuçlarını izleyen çok sayıda göz küresine sahiptir.
15
blueberryfields

Derleyicileri günlük olarak kullanıyoruz

... derleyicileri nasıl bu kadar güvenilir yapıyorlar?

Yapmazlar. Yaparız. Herkes onları her zaman kullandığından, hatalar hızlı bir şekilde bulunur.

Bu bir sayı oyunu. Derleyiciler çok yaygın olarak kullanıldığından, herhangi bir hatanın birileri tarafından tetiklenmesi olasıdır, ancak çok sayıda kullanıcı olduğu için, yüksek oranda birisinin özellikle sizin olacağınız pek olası değildir .

Yani, bakış açınıza bağlıdır: tüm kullanıcılar arasında derleyiciler buggy. Ama muhtemelen bir başkası sizden önce benzer bir kod derlemiş olacak, bu yüzden bir hata bir hata olsaydı, , siz değilsiniz, bu yüzden bireysel bakış açınızdan, hatanın asla orada olmadığı anlaşılıyor.

Tabii ki, bunun üzerine, diğer tüm cevapları buraya ekleyebilirsiniz: derleyiciler iyi araştırılmış, iyi anlaşılmıştır. Yazmaları zor olan bu efsane var, bu da sadece çok akıllı, çok iyi programcıların aslında bir tane yazmaya çalıştıkları ve yaptıkları zaman çok dikkatli oldukları anlamına geliyor. Genellikle test edilmesi kolay, stres testi veya tüy testi kolaydır. Derleyici kullanıcıları, uzman programcılar olma eğilimindedir ve bu da yüksek kaliteli hata raporlarına yol açar. Ve tam tersi: derleyici yazarları kendi derleyicilerinin kullanıcıları olma eğilimindedir.

14
Jörg W Mittag

Zaten tüm cevaplara ek olarak, eklemek istiyorum:

Ben inanıyorum birçok kez, satıcılar kendi köpek mamasını yiyorlar. Yani derleyicileri kendi başlarına yazıyorlar.

12
DevSolo

Sık sık derleyici hatalarıyla karşılaştım.

Onları daha az test edicinin olduğu daha karanlık köşelerde bulabilirsiniz. Örneğin, GCC'deki hataları bulmak için şunları denemelisiniz:

  • Çapraz derleyici oluşturun. GCC'nin yapılandırma ve oluşturma komut dosyalarında tam anlamıyla onlarca hata bulacaksınız. Bazıları GCC derlemesi sırasında derleme hatalarına neden olurken, diğerleri çapraz derleyicinin çalışma yürütülebilir dosyaları oluşturamamasına neden olur.
  • Profile-bootstrap kullanarak GCC'nin Itanium sürümünü oluşturun. Son birkaç kez bunu GCC 4.4 ve 4.5 üzerinde denedim, çalışan bir C++ istisna işleyicisi üretemedi. Optimize edilmemiş yapı iyi çalıştı. Kimse bildirdiğim hatayı düzeltmekle ilgilenmiyor gibiydi ve GCC asm bellek özelliklerinde kırılan şeyleri araştırmaya çalıştıktan sonra kendimi düzeltmeyi bıraktım.
  • Bir dağıtım oluşturma komut dosyası izlemeden en son öğelerden kendi çalışan GCJ'nizi oluşturmayı deneyin. Sana meydan okuyorum.
8
Zan Lynx

Birkaç neden:

  • Derleyici yazarları "kendi köpek mamasını yiyin".
  • Derleyiciler CS --- iyi anlaşılmış ilkelere dayanmaktadır.
  • Derleyiciler çok net spec.
  • Derleyiciler test edildi alır.
  • Derleyiciler her zaman çok güvenilir değildir.
6
Kramii

-O0'da genellikle çok iyidirler. Aslında, bir derleyici hatasından şüphelenirsek, -O0 ile kullanmaya çalıştığımız her seviyeyi karşılaştırırız. Daha yüksek optimizasyon seviyeleri daha büyük risk taşır. Hatta bazıları kasten böyledir ve belgelerde bu şekilde etiketlenmiştir. Çok fazla karşılaştım (zamanım boyunca en az yüz), ama son zamanlarda daha nadir hale geliyorlar. Bununla birlikte, iyi specmark sayılarının (veya pazarlama için önemli olan diğer kriterlerin) peşinde, limitleri zorlama cazibesi harika. Birkaç yıl önce bir satıcı (isimsiz gitmek için) parantezin varsayılanını ihlal etmeye karar verdiğinde sorun yaşadık - bazı özel açıkça etiketlenmiş derleme seçeneklerinden daha.

Bir derleyici hatasını, bir sapan bellek referansına karşı koymak zor olabilir, farklı seçeneklerle yeniden derleme, veri nesnelerinin bellek içindeki göreli konumlandırmasını karıştırabilir, bu yüzden kaynak kodunuzun Heisenbug veya bir buggy olup olmadığını bilmiyorsunuz derleyici. Ayrıca birçok optimizasyon işlem sırasında meşru değişiklikler yapar ve hatta cebirinizde cebirsel sadeleştirmeler yapar ve bunlar kayan nokta yuvarlaması ve alt/taşma açısından farklı özelliklere sahiptir. Bu etkileri GERÇEK böceklerden ayırmak zordur. Bu nedenle, sert çekirdekli kayan nokta hesaplaması zordur, çünkü hataların ve sayısal hassasiyetin çözülmesi genellikle kolay değildir.

5
Omega Centauri

Derleyici hataları o kadar nadir değildir. En yaygın durum, bir derleyicinin kabul edilmesi gereken kodla ilgili bir hata bildirmesi veya bir derleyicinin reddedilmesi gereken kodu kabul etmesidir.

5
kevin cline

Hiç derleyicinin kendisinde bir hatayla karşılaştınız mı? Nedir ve sorunun derleyicinin kendisinde olduğunu nasıl anladınız?

Evet!

En unutulmaz ikisi, karşılaştığım ilk ikisi. Her ikisi de yaklaşık 1985-7 yıllarında 680x0 Mac için Lightspeed C derleyicisindeydi.

Birincisi, bazı durumlarda, tamsayı postincrement operatörü hiçbir şey yapmadı - başka bir deyişle, belirli bir kod parçasında, "i ++" sadece "i" için hiçbir şey yapmadı. Bir demonte edene kadar saçımı çekiyordum. Sonra artımı farklı bir şekilde yaptım ve bir hata raporu gönderdim.

İkincisi biraz daha karmaşıktı ve gerçekten kötüleşen kötü düşünülmüş bir "özellik" idi. İlk Mac'lerde düşük seviyeli disk işlemleri yapmak için karmaşık bir sistem vardı. Herhangi bir nedenden ötürü hiç anlamadım - muhtemelen daha küçük yürütülebilir dosyalar oluşturmakla ilgili olmak zorundayım - derleyici sadece nesne kodunda disk operasyon talimatlarını oluşturmak yerine, çalışma hızı disk çalışmasını oluşturan dahili bir işlevi çağıracaktı talimatlar yığını ve orada atladı.

Bu 68000 CPU'da harika çalıştı, ancak aynı kodu bir 68020 CPU'da çalıştırdığınızda, genellikle garip şeyler yapardı. 68020'nin yeni bir özelliğinin 256 baytlık bir ilkel komut önbelleği olduğu ortaya çıktı. Bu CPU önbellekleri ile ilk günler, önbellek "kirli" ve yeniden doldurulması gerektiğini hiçbir fikri yoktu; Sanırım Motorola'daki CPU tasarımcıları kendi kendini değiştiren kod hakkında düşünmediler. Bu nedenle, yürütme dizinizde yeterince yakın iki disk işlemi yaptıysanız ve Lightspeed çalışma zamanı, gerçek talimatları yığın üzerinde aynı konumda oluşturduysa, CPU yanlışlıkla bir komut önbelleğine sahip olduğunu ve ilk disk işlemini iki kez çalıştırdığını düşünür.

Yine, bunun bir sökücü ile bir miktar kazma ve düşük seviyeli bir hata ayıklayıcıda çok fazla adım atması gerektiğini anlamak. Geçici çözümüm, her disk işlemine 256 "NOP" talimatı uygulayan ve talimat önbelleğini su bastıran (ve dolayısıyla temizlenen) bir fonksiyon çağrısıyla önek eklemekti.

O zamandan bu yana geçen 25 yıllık sürede, zaman içinde daha az ve daha az derleyici hatası gördüm. Bunun birkaç nedeni olduğunu düşünüyorum:

  • Derleyiciler için sürekli artan bir dizi doğrulama testi vardır.
  • Modern derleyiciler tipik olarak iki veya daha fazla parçaya bölünür, bunlardan biri platformdan bağımsız kod üretir (örneğin LLVM'nin hayali bir CPU olarak düşünebileceğiniz şeyi hedefler) ve diğeri bunu gerçek hedef donanımınız için talimatlara dönüştürür. Çok platformlu derleyicilerde, ilk bölüm her yerde kullanılır, bu yüzden tonlarca gerçek dünya testi alır.
4
Bob Murphy

5.5 yıl önce Turbo Pascal'da göze çarpan bir hata buldu. Derleyicinin önceki (5.0) veya sonraki (6.0) sürümünde bir hata yok. Ve hiç de bir köşe çantası olmadığı için test edilmesi kolay bir şeydi (sadece yaygın olarak kullanılmayan bir çağrı).

Genel olarak, kesinlikle ticari derleyici üreticileri (hobi projeleri yerine) çok kapsamlı KG ve test prosedürlerine sahip olacaklardır. Derleyicilerinin amiral gemisi projeleri olduğunu ve kusurların üzerlerinde çok kötü görüneceğini, diğer birçok ürünü üreten diğer şirketlere baktıklarından daha kötü olacağını biliyorlar. Yazılım geliştiricileri affetmeyen bir gruptur, araç tedarikçilerimiz bizi tedarikçiden bir düzeltme beklemek yerine alternatifler aramaya gideceğimize izin veriyor ve bu gerçeği, misal. Diğer birçok sektörde durum böyle değil, bu yüzden ciddi bir hata sonucu bir derleyici üreticisine olan potansiyel kayıp, bir video düzenleme yazılımı üreticisi demekten çok daha büyük.

4
jwenting

Evet, sadece dün ASP.NET derleyicisinde bir hatayla karşılaştım:

Görünümlerde güçlü yazılan modelleri kullandığınızda, şablonların kaç parametre içerebileceğine ilişkin bir sınır vardır. Açıkçası 4'ten fazla şablon parametresi alamaz, böylece aşağıdaki her iki örnek de derleyicinin işlemesini çok fazla hale getirir:

ViewUserControl<System.Tuple<type1, type2, type3, type4, type5>>

Olduğu gibi derlenmez, ancak type5 kaldırıldı.

ViewUserControl<System.Tuple<MyModel, System.Func<type1, type2, type3, type4>>>

type4 kaldırıldı.

Bunu not et System.Tuple birçok aşırı yüke sahiptir ve 16 parametreye kadar sürebilir (biliyorum deli).

3
user8685

Derleyici hataları olur, ancak bunları tek köşelerde bulma eğilimindesiniz ...

1990'larda Digital Equipment Corporation VAX VMS C derleyicisinde garip bir hata oldu

(Kemerimde soğan vardı, o zamanki moda gibi)

For döngüsünün önünde herhangi bir yerde yabancı bir noktalı virgül, for döngüsünün gövdesi olarak derlenir.

f(){...}
;
g(){...}

void test(){
  int i;
  for ( i=0; i < 10; i++){
     puts("hello");
  }
}

Söz konusu derleyicide, döngü yalnızca bir kez yürütülür.

görür

f(){...}
g(){...}

void test(){
  int i;
  for ( i=0; i < 10; i++) ;  /* empty statement for fun */

  {
     puts("hello");
  }
}

Bu bana çok zaman harcadı.

İş deneyimine uyguladığımız (eskiden) PIC C derleyicisinin eski sürümü, yüksek öncelikli kesmeyi doğru şekilde kullanan kod üretemedi. 2-3 yıl beklemeniz ve yükseltmeniz gerekiyordu.

MSVC 6 derleyicisinin bağlayıcıda şık bir hatası vardı, bölümleme hatası olurdu ve zaman zaman sebepsiz yere ölecekti. Temiz bir yapı genellikle onu düzeltti (ama iç çeker her zaman değil).

3
Tim Williscroft

Yazılımınızın davranışı -O0 ve -O2 ile derlendiğinde farklı olduğunda, bir derleyici hatası buldunuz.

Yazılımınızın davranışı beklediğinizden farklı olduğunda, hata kodunuzda olabilir.

2
mouviciel

Aviyonik yazılım gibi bazı etki alanlarında, kod ve donanımın yanı sıra derleyici üzerinde son derece yüksek sertifika gereksinimleri vardır. Bu son bölüm hakkında, Compcert adlı resmi olarak doğrulanmış bir C derleyicisi oluşturmayı amaçlayan bir proje var. Teorik olarak, bu tür bir derleyici geldikleri kadar güvenilirdir.

2
Axel

Birkaç derleyici hata gördüm, birkaç kendimi rapor (özellikle, F #).

Bununla birlikte, derleyici hatalarının nadir olduğunu düşünüyorum çünkü derleyici yazan insanlar genellikle kodun matematiksel etkileri hakkında gerçekten bilinçli hale getiren bilgisayar biliminin titiz kavramlarıyla çok rahatlar.

Çoğu muhtemelen lambda hesabı, resmi doğrulama, anlamsal anlambilim gibi şeylere çok aşinadır - benim gibi ortalama bir programcının ancak zar zor kavrayabileceği şeyler.

Ayrıca, genellikle derleyicilerdeki girdiden çıktıya oldukça basit bir eşleme vardır, bu nedenle bir programlama dilinde hata ayıklama, örneğin bir blog motoru hata ayıklamadan çok daha kolaydır.

2
Rei Miyasaka

C # derleyicisinde çok uzun zaman önce bir hata buldum, Eric Lippert'in (C # tasarım ekibinde bulunan) hatanın ne olduğunu nasıl anladığını görebilirsiniz burada .

Daha önce verilen cevaplara ek olarak, birkaç şey daha eklemek istiyorum. Derleyici tasarımcıları genellikle son derece iyi programcılardır. Derleyiciler çok önemlidir: Çoğu programlama derleyiciler kullanılarak yapılır, bu nedenle derleyicinin yüksek kalitede olması şarttır. Bu nedenle, en iyi kişilerini üzerine koymak için derleyici yapan şirketlerin çıkarına (veya en azından çok iyi olanlara: en iyileri derleyici tasarımını beğenmeyebilir). Microsoft, C ve C++ derleyicilerinin düzgün çalışmasını çok ister veya şirketin geri kalanı işlerini yapamaz.

Ayrıca, gerçekten karmaşık bir derleyici oluşturuyorsanız, onu birlikte hackleyemezsiniz. Derleyicilerin arkasındaki mantık hem oldukça karmaşık hem de resmileştirilmesi kolaydır. Bu nedenle, bu programlar genellikle daha az hata ile sonuçlanma eğiliminde olan çok 'sağlam' ve genel bir şekilde oluşturulacaktır.

2
Alex ten Brink