Templat C ++ terkenal karena menghasilkan pesan kesalahan yang panjang dan tidak dapat dibaca. Saya punya ide umum mengapa pesan kesalahan template di C ++ sangat buruk. Pada dasarnya, masalahnya adalah bahwa kesalahan tidak dipicu sampai kompilator menemukan sintaks yang tidak didukung oleh tipe tertentu dalam templat. Sebagai contoh:
template <class T>
void dosomething(T& x) { x += 5; }
Jika T
tidak mendukung +=
operator, kompiler akan menghasilkan pesan kesalahan. Dan jika ini terjadi jauh di dalam perpustakaan di suatu tempat, pesan kesalahan mungkin ribuan baris.
Tapi template C ++ pada dasarnya hanya sebuah mekanisme untuk mengetik bebek waktu kompilasi. Kesalahan template C ++ secara konseptual sangat mirip dengan kesalahan tipe runtime yang mungkin terjadi dalam bahasa dinamis seperti Python. Misalnya, pertimbangkan kode Python berikut:
def dosomething(x):
x.foo()
Di sini, jika x
tidak memiliki foo()
metode, interpreter Python melempar pengecualian, dan menampilkan jejak stack bersama dengan pesan kesalahan yang cukup jelas yang menunjukkan masalah. Bahkan jika kesalahan tidak dipicu sampai penerjemah berada jauh di dalam beberapa fungsi perpustakaan, pesan runtime-error masih belum mendekati seburuk muntah yang tidak terbaca dimuntahkan oleh kompiler C ++ khas. Jadi mengapa kompiler C ++ tidak bisa lebih jelas tentang apa yang salah? Mengapa beberapa pesan kesalahan templat C ++ benar-benar menyebabkan jendela konsol saya bergulir selama lebih dari 5 detik?
sumber
clang++
mengedipkan mata).Jawaban:
Pesan kesalahan templat mungkin terkenal, tetapi tidak selalu panjang dan tidak dapat dibaca. Dalam hal ini, seluruh pesan kesalahan (dari gcc) adalah:
Seperti dalam contoh Python Anda, Anda mendapatkan "tumpukan jejak" poin instantiasi templat, dan pesan kesalahan yang jelas menunjukkan masalah.
Terkadang, pesan kesalahan terkait templat bisa lebih lama, karena berbagai alasan:
Perbedaan utama dari Python adalah sistem tipe statis, yang mengarah pada keharusan memasukkan nama tipe (terkadang panjang) dalam pesan kesalahan. Tanpa mereka, kadang-kadang akan sangat sulit untuk mendiagnosis mengapa resolusi kelebihan gagal. Dengan mereka, tantangan Anda bukan lagi untuk menebak di mana masalahnya, tetapi untuk menguraikan hieroglif yang memberi tahu Anda di mana itu.
Juga, memeriksa pada saat runtime berarti bahwa program akan berhenti pada kesalahan pertama yang ditemui, hanya menampilkan satu pesan. Kompiler mungkin menampilkan semua kesalahan yang ditemui, sampai menyerah; setidaknya di C ++, itu tidak boleh berhenti pada kesalahan pertama dalam file, karena itu mungkin merupakan konsekuensi dari kesalahan nanti.
sumber
Beberapa alasan yang jelas termasuk:
Itu jauh dari lengkap, tetapi Anda mendapatkan ide umum. Bahkan jika itu tidak mudah, sebagian besar dapat disembuhkan. Selama bertahun-tahun, saya telah memberi tahu orang-orang untuk mendapatkan salinan Comeau C ++ untuk penggunaan reguler; Saya mungkin telah menyimpan cukup dari satu pesan kesalahan satu kali untuk membayar kompiler. Sekarang Dentang mencapai titik yang sama (dan bahkan lebih murah).
Saya akan menutup dengan pengamatan umum yang terdengar seperti lelucon, tetapi sebenarnya tidak. Sebagian besar waktu, pekerjaan nyata kompiler secara jujur adalah mengubah kode sumber menjadi pesan kesalahan. Sudah saatnya vendor berkonsentrasi melakukan pekerjaan itu sedikit lebih baik - meskipun saya akan secara terbuka mengakui bahwa ketika saya telah menulis kompiler, saya memiliki kecenderungan yang kuat untuk memperlakukannya sebagai sekunder (paling-paling) dan dalam beberapa kasus hampir mengabaikannya. sama sekali.
sumber
Jawaban sederhananya adalah, karena Python dirancang untuk bekerja seperti itu, sedangkan banyak hal yang terkait dengan template muncul secara tidak sengaja. Itu tidak pernah dimaksudkan untuk menjadi sistem Turing-lengkap untuk dirinya sendiri, misalnya. Dan jika Anda tidak dapat dengan sengaja merencanakan dan alasan tentang apa yang terjadi ketika sistem Anda bekerja , mengapa ada orang yang mengharapkan perencanaan yang cermat dan bijaksana tentang apa yang terjadi ketika terjadi kesalahan?
Juga, seperti yang Anda tunjukkan, interpreter Python dapat mempermudah Anda dengan menampilkan jejak stack karena itu mengartikan kode Python. Jika kompiler C ++ hits kesalahan template dan memberi Anda jejak stack, itu akan sama tidak membantu seperti "template muntah," bukan?
sumber