C ++ şablon hata mesajları neden bu kadar korkunç?


28

C ++ şablonları uzun, okunamayan hata mesajları üretme konusunda ünlüdür. C ++ şablonunda hata iletilerinin neden bu kadar kötü olduğu konusunda genel bir fikrim var. Temel olarak sorun, derleyici bir şablonda belirli bir tür tarafından desteklenmeyen sözdizimi ile karşılaşıncaya kadar hatanın tetiklenmemesidir. Örneğin:

template <class T>
void dosomething(T& x) { x += 5; }

Eğer Tdesteklemiyorsa +=operatörü, derleyici bir hata mesajı oluşturur. Ve eğer bu bir yerde bir kütüphanenin derinliklerinde olursa, hata mesajı binlerce satır uzunluğunda olabilir.

Ancak C ++ şablonları aslında sadece derleme zamanı ördek yazma için bir mekanizmadır. Bir C ++ şablon hatası kavramsal olarak Python gibi dinamik bir dilde oluşabilecek bir çalışma zamanı tipine benzer. Örneğin, aşağıdaki Python kodunu göz önünde bulundurun:

def dosomething(x):
   x.foo()

Burada, xbir foo()yönteme sahip değilse , Python yorumlayıcısı bir istisna atar ve sorunu belirten oldukça açık bir hata mesajı ile birlikte bir yığın izlemesi görüntüler. Hata, yorumlayıcı bazı kütüphane işlevlerinin derinliklerine kadar tetiklenmese bile, çalışma zamanı hata mesajı, tipik bir C ++ derleyicisinin yaydığı okunamayan kusmuk kadar kötü değildir. Peki neden bir C ++ derleyicisi neyin yanlış gittiği konusunda daha net olamıyor? Neden bazı C ++ şablon hata mesajları tam anlamıyla konsol penceremin 5 saniyeden fazla bir süre boyunca kaymasına neden oluyor?


6
Bazı derleyiciler korkunç hata mesajlarına sahiptir, ancak bazıları gerçekten iyidir ( clang++göz kırpması).
Benjamin Bannier,

2
Yani, programlarınızın derleme zamanında başarısız olmak yerine, bir müşterinin elinde, sevk anında çalışmasını, tercih etmesini mi istiyorsunuz?
P,

13
@Pavel, hayır. Bu soru, çalışma zamanının vs derleme zamanı hata denetiminin avantajları / dezavantajları ile ilgili değildir.
Kanal72

1
Büyük C ++ şablon hatalarına bir örnek olarak, FWIW: codegolf.stackexchange.com/a/10470/7174
kebs

Yanıtlar:


28

Şablon hata mesajları meşhur olabilir, fakat hiçbir zaman uzun ve okunaksız değildir. Bu durumda, hata mesajının tamamı (gcc'den) şudur:

test.cpp: In function void dosomething(T&) [with T = X]’:
test.cpp:11:   instantiated from here
test.cpp:6: error: no match for operator+=’ in x += 5

Python örneğinde olduğu gibi, şablon başlatma noktalarının "yığın izlemesi" ve sorunu belirten açık bir hata mesajı alırsınız.

Bazen, şablonla ilgili hata mesajları, çeşitli nedenlerle daha uzun sürebilir:

  • "Yığın izi" çok daha derin olabilir
  • Şablonlar argümanlar olarak diğer şablonlarla başlatıldıkça ve tüm isimlendirme nitelikleriyle gösterildiğinden, tür adları çok daha uzun olabilir.
  • Aşırı yük çözünürlüğü başarısız olduğunda, hata mesajı aday aşırı yüklemelerin bir listesini içerebilir (her biri çok uzun tür adlar içerebilir)
  • Aynı yerde, geçersiz bir şablonun birçok yerde başlatılması durumunda aynı hata bildirilebilir.

Python'dan temel fark statik tip sistemdir ve hata mesajına (bazen uzun) tip adlarını dahil etme zorunluluğuna yol açar. Onlar olmadan, bazen aşırı yük çözünürlüğünün neden başarısız olduğunu teşhis etmek zor olabilir . Onlarla mücadeleniz artık sorunun nerede olduğunu tahmin etmek değil, size nerede olduğunu söyleyen hiyeroglifleri deşifre etmek.

Ayrıca, çalışma zamanında kontrol etmek, programın karşılaştığı ilk hatada duracağı ve yalnızca tek bir mesaj görüntüleneceği anlamına gelir. Bir derleyici, pes edinceye kadar karşılaştığı tüm hataları görüntüleyebilir; en azından C ++ 'da, dosyadaki ilk hatayı durdurmamalıdır, çünkü bu daha sonraki bir hatanın bir sonucu olabilir.


4
Daha sonra yapılan bir hatanın sonucu olan bir hata örneği verebilir misiniz?
Ruslan,

12

Açık nedenlerden bazıları şunlardır:

  1. Tarihçe. Gcc, MSVC, vb. Yeniyken, daha iyi hata mesajları üretmek için veri depolamak için çok fazla alan kullanamazlardı. Hafıza, yapamayacakları kadar kıttı.
  2. Yıllar boyunca, tüketiciler hata mesajı kalitesini görmezden geldiler, bu nedenle satıcılar çoğunlukla bunu yaptı.
  3. Bazı kodlarla, derleyici daha sonra kodun içindeki gerçek hataları yeniden senkronize edebilir ve tanılayabilir. Şablonlardaki hatalar o kadar kötü basar ki, birinciden önceki bir şey neredeyse her zaman işe yaramazdır.
  4. Şablonların genel esnekliği, kodunuzda bir hata olduğunda muhtemelen ne demek istediğinizi tahmin etmeyi zorlaştırır .
  5. Bir şablonda, bir adın anlamı hem şablonun içeriğine hem de başlatmanın içeriğine ve bağımsız değişkene bağlı aramaya daha fazla olasılık ekleyebilir.
  6. Fonksiyon aşırı yükleme sağlayabilir çok özel bir işlev çağrısı için ne aday olabilir bakın ve bazı derleyiciler (örneğin gcc) bir belirsizlik olmaması bütün zaman aldatılan bunları listelemek.
  7. Geçilen değerlerin gereksinimleri karşıladığından emin olmadan normal parametreler kullanmayı asla düşünmeyen birçok kodlayıcı, şablon parametrelerini hiç kontrol etmeyi bile denemez (ve itiraf etmeliyim ki, buna kendim de bakarım).

Çok yorucu değil, ama genel fikrin var. Kolay olmasa bile çoğu iyileştirilebilir. Yıllardır, insanlara düzenli kullanım için Comeau C ++ 'nın bir kopyasını almalarını söyledim; Muhtemelen derleyiciye ödeme yapmak için bir seferde bir hata mesajından yeterince tasarruf ettim. Şimdi Clang aynı noktaya geliyor (ve daha da pahalı).

Şaka gibi görünen genel bir gözlemle yaklaşacağım, ama gerçekten değil. Çoğu zaman, bir derleyicinin gerçek işi dürüst olmak gerekirse , kaynak kodunu hata mesajlarına dönüştürmektir. Satıcıların bu işi biraz daha iyi yapmaya odaklanmalarının zamanı gelmişti - derleyici olarak yazarken, ikincil olarak (en iyi ihtimalle) görmezden gelme eğiliminde olduğumu ve bazı durumlarda neredeyse görmezden geldiğimi açıkça itiraf etmeme rağmen tamamen.


9

Basit cevap, çünkü Python bu şekilde çalışmak üzere tasarlandı, oysa şablonlarla ilgili pek çok şey kazara ortaya çıktı. Örneğin, hiçbir zaman kendi başına bir Turing-komple sistem olmak niyetinde değildi. Ve eğer sisteminiz çalıştığında ne olacağını kasıtlı olarak planlayamıyor ve neden düşünemiyorsanız , neden bir şeyler ters gittiğinde ne olacağı konusunda dikkatli, düşünceli bir planlama yapmayı beklemeli?

Ayrıca, belirttiğiniz gibi, Python yorumlayıcısı Python kodunu yorumladığından yığın izi görüntüleyerek sizin için çok daha kolay bir hale getirebilir. Bir C ++ derleyicisi bir şablon hatasını vurursa ve size bir yığın izlemesi verirse, bu "şablon kusması" kadar yararsız olur, değil mi?

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.