Kenapa kompiler begitu bisa diandalkan?

64

Kami menggunakan kompiler setiap hari seolah-olah kebenarannya diberikan, tetapi kompiler juga merupakan program, dan berpotensi mengandung bug. Saya selalu bertanya-tanya tentang ketahanan sempurna ini. Pernahkah Anda menemukan bug di kompiler itu sendiri? Apa itu dan bagaimana Anda menyadari masalahnya ada di kompiler itu sendiri?

... dan bagaimana cara mereka membuat kompiler sangat handal?

EpsilonVector
sumber
16
Nah, mereka mengkompilasi kompiler di dalamnya ...
Michael K
31
Mereka tidak sempurna. Ada bug kompiler - hanya saja mereka sangat jarang.
ChrisF
5
Bug menjadi lebih jarang saat Anda menuruni tumpukan kode: bug aplikasi lebih umum daripada bug penyusun. Bug kompiler lebih umum daripada bug CPU (mikrokode). Ini sebenarnya berita baik: bisakah Anda bayangkan jika sebaliknya?
Fixee
Anda mungkin belajar sesuatu dengan mengamati bagaimana kompiler yang memang memiliki banyak bug (seperti sdcc!) Berbeda dari kompiler seperti gcc yang jauh lebih kuat dan dapat diandalkan.
Ben Jackson
5
VC ++ 6 memiliki bug.
Mateen Ulhaq

Jawaban:

97

Mereka diuji secara menyeluruh melalui penggunaan oleh ribuan atau bahkan jutaan pengembang dari waktu ke waktu.

Juga, masalah yang harus dipecahkan didefinisikan dengan baik (dengan spesifikasi teknis yang sangat rinci). Dan sifat tugas cocok dengan mudah untuk tes unit / sistem. Yaitu pada dasarnya menerjemahkan input tekstual dalam format yang sangat spesifik untuk output dalam jenis lain dari format yang terdefinisi dengan baik (semacam bytecode atau kode mesin). Sehingga mudah untuk membuat dan memverifikasi kasus uji.

Selain itu, biasanya bug juga mudah direproduksi: terlepas dari platform yang tepat dan info versi kompiler, biasanya yang Anda butuhkan hanyalah sepotong kode input. Belum lagi bahwa pengguna kompiler (menjadi pengembang sendiri) cenderung memberikan laporan bug yang jauh lebih tepat dan terperinci daripada pengguna komputer rata-rata :-)

Péter Török
sumber
32
Ditambah banyak kode kompiler mungkin dapat dibuktikan benar.
biziclop
@biziclop, poin bagus, ini adalah konsekuensi lain dari sifat khusus tugas tersebut.
Péter Török
Kompiler lengkap pertama ditulis pada tahun 1957 untuk bahasa FORTRAN oleh John Backus. Jadi, Anda tahu, teknologi kompiler berusia lebih dari 50 tahun. Kami telah memiliki cukup waktu untuk memperbaikinya, meskipun, seperti yang ditunjukkan orang lain, kompiler memang memiliki bug.
leed25d
@biziclop, pada kenyataannya, beberapa komponen seperti lexer dan parser bahkan dapat di-autogenerasi dari tata bahasa, yang sekali lagi menurunkan risiko bug (asalkan generator lexer / parser kuat - seperti biasanya, untuk alasan yang sama seperti yang tercantum di atas) .
Péter Török
2
@ Péter: Generator Lexer / parser tampaknya agak jarang di kompiler yang lebih banyak digunakan - kebanyakan menulis lexer dan parser dengan tangan karena berbagai alasan, termasuk kecepatan dan kurangnya generator parser / lexer yang cukup pintar untuk bahasa yang dimaksud (misalnya C ).
61

Selain semua jawaban bagus sejauh ini:

Anda memiliki "bias pengamat". Anda tidak mengamati bug, dan karena itu Anda menganggap tidak ada bug.

Dulu saya berpikir seperti Anda. Kemudian saya mulai menulis kompiler secara profesional, dan biarkan saya memberitahu Anda, ada banyak bug di sana!

Anda tidak melihat bug karena Anda menulis kode yang hanya seperti 99,999% dari semua kode yang ditulis orang. Anda mungkin menulis kode yang benar-benar normal, langsung, dan benar, yang memanggil metode dan menjalankan loop dan tidak melakukan sesuatu yang mewah atau aneh, karena Anda adalah pengembang normal yang menyelesaikan masalah bisnis normal.

Anda tidak melihat bug penyusun karena bug penyusun tidak ada dalam skenario kode normal yang mudah dianalisa; bug ada dalam analisis kode aneh yang tidak Anda tulis.

Saya di sisi lain memiliki bias pengamat yang berlawanan. Saya melihat kode gila sepanjang hari setiap hari, dan bagi saya para kompiler sepertinya penuh dengan bug.

Jika Anda duduk dengan spesifikasi bahasa dari bahasa apa pun, dan mengambil implementasi kompiler apa pun untuk bahasa itu, dan benar-benar berusaha keras untuk menentukan apakah kompiler benar-benar mengimplementasikan spesifikasi atau tidak, berkonsentrasi pada kasus sudut yang tidak jelas, segera Anda akan menemukan bug kompiler cukup sering. Biarkan saya memberi Anda sebuah contoh, inilah bug kompiler C # yang saya temukan secara harfiah lima menit yang lalu.

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

Kompiler memberikan tiga kesalahan.

  • Argumen ref atau out harus merupakan variabel yang dapat ditugaskan.
  • Kecocokan terbaik untuk N (ref int x) memiliki argumen yang tidak valid.
  • Tidak ada "ref" pada argumen 1.

Jelas pesan kesalahan pertama sudah benar dan yang ketiga adalah bug. Algoritma generasi kesalahan sedang mencoba mencari tahu mengapa argumen pertama tidak valid, terlihat pada argumen itu, melihat bahwa argumen tersebut adalah konstanta, dan tidak kembali ke kode sumber untuk memeriksa apakah argumen itu ditandai sebagai "ref"; melainkan mengasumsikan bahwa tidak ada orang yang cukup bodoh untuk menandai sebuah konstanta sebagai referensi, dan memutuskan bahwa referensi tersebut harus hilang.

Tidak jelas apa pesan kesalahan ketiga yang benar, tetapi ini bukan. Bahkan, tidak jelas apakah pesan kesalahan kedua juga benar. Haruskah resolusi kelebihan gagal, atau haruskah "ref 123" diperlakukan sebagai argumen ref dari jenis yang benar? Sekarang saya harus memikirkannya dan membicarakannya dengan tim triase sehingga kita dapat menentukan apa perilaku yang benar.

Anda belum pernah melihat bug ini karena Anda mungkin tidak akan pernah melakukan sesuatu yang konyol untuk mencoba melewati 123 oleh ref. Dan jika Anda melakukannya, Anda mungkin bahkan tidak akan melihat bahwa pesan kesalahan ketiga adalah tidak masuk akal, karena yang pertama sudah benar dan cukup untuk mendiagnosis masalah. Tetapi saya mencoba melakukan hal-hal seperti itu, karena saya mencoba untuk memecahkan kompiler. Jika Anda mencoba, Anda akan melihat bug juga.

Eric Lippert
sumber
4
Pesan kesalahan yang baik setelah yang pertama sangat sulit dilakukan.
Tentu saja harus ada energi yang dihabiskan lebih baik daripada membuat kompiler benar-benar "bodoh" -tahan :)
Homde
2
@MKO: Tentu saja. Banyak bug tidak diperbaiki. Kadang-kadang perbaikannya sangat mahal dan skenarionya begitu tidak jelas sehingga biayanya tidak sesuai dengan manfaatnya. Dan kadang-kadang cukup banyak orang yang mengandalkan perilaku "kereta" yang harus Anda pertahankan.
Eric Lippert
mmm ... bug yang berakhir dengan pesan kesalahan "baik". Itu selalu mungkin untuk mengutak-atik kode sedikit untuk membuatnya berfungsi. Bagaimana dengan bug di mana kompiler menerima kode sumber dan menghasilkan output assmebly "salah". Itu menakutkan
Gianluca Ghettini
7
@aij: Benar dalam arti "kode C # yang jelas legal". Misalnya, apakah Anda pernah menulis sebuah program yang berisi antarmuka yang mewarisi dua antarmuka di mana satu antarmuka memiliki properti dan yang lainnya memiliki metode dengan nama yang sama dengan properti? Cepat, tanpa melihat spesifikasi: apakah itu legal ? Sekarang anggaplah Anda memiliki panggilan ke metode itu; apakah ini ambigu ? Dan seterusnya. Orang-orang menulis kode yang tidak melakukan apa yang mereka maksud sepanjang waktu. Tetapi jarang mereka menulis kode di mana Anda harus menjadi seorang ahli spesifikasi untuk mengatakan apakah itu C # legal.
Eric Lippert
52

Apakah kamu bercanda? Kompiler juga memiliki bug, benar-benar memuat.

GCC mungkin adalah kompiler open source paling terkenal di planet ini dan lihat database bug-nya: http://gcc.gnu.org/bugzilla/buglist.cgi?product=gcc&component=c%2B%2B&resolution=-- -

Antara GCC 3.2 dan GCC 3.2.3 lihat berapa banyak bug diperbaiki: http://gcc.gnu.org/gcc-3.2/changes.html

Adapun orang lain seperti Visual C ++, saya bahkan tidak ingin memulai.

Bagaimana Anda membuat kompiler dapat diandalkan? Sebagai permulaan, mereka memiliki banyak dan banyak unit test. Dan seluruh planet menggunakannya sehingga tidak ada kekurangan penguji.

Serius meskipun, pengembang kompiler saya suka percaya adalah programmer unggul dan sementara mereka tidak sempurna mereka dikemas dalam pukulan yang cukup.

Fanatic23
sumber
19

Saya telah menemukan dua atau tiga di hari saya. Satu-satunya cara nyata untuk mendeteksi seseorang adalah dengan melihat kode perakitan.

Meskipun kompiler sangat dapat diandalkan karena alasan yang ditunjukkan poster lain, saya pikir keandalan kompiler seringkali merupakan penilaian yang memuaskan sendiri. Programmer cenderung melihat compiler sebagai standar. Ketika terjadi kesalahan, Anda menganggap itu salah Anda (karena 99,999% dari waktu itu), dan mengubah kode Anda untuk mengatasi masalah kompiler daripada sebaliknya. Misalnya, kode mogok di bawah pengaturan optimasi tinggi jelas merupakan bug penyusun, tetapi kebanyakan orang hanya mengaturnya sedikit lebih rendah dan melanjutkan tanpa melaporkan bug.

Karl Bielefeldt
sumber
6
+1 untuk "melihat kompiler sebagai standar." Saya sudah lama berpendapat bahwa ada dua hal yang benar-benar mendefinisikan bahasa: kompiler dan perpustakaan standar. Dokumen standar hanyalah dokumentasi.
Mason Wheeler
8
@ Alasan: Itu bekerja dengan baik untuk bahasa dengan satu implementasi. Untuk bahasa dengan banyak, standarnya sangat penting. Dampak kehidupan nyata adalah bahwa, jika Anda mengeluh tentang sesuatu, vendor akan menganggap Anda serius jika itu masalah standar, dan mengabaikan Anda jika itu perilaku yang tidak jelas atau sesuatu seperti itu.
David Thornley
2
@ Alasan - Itu hanya karena sangat sedikit bahasa yang memiliki standar dan / yang mereka patuhi. Itu, btw, IMHO, bukan hal yang baik - untuk segala jenis perkembangan serius, yang diharapkan akan bertahan lebih dari satu generasi OS.
Benteng
1
@ David: Atau lebih tepatnya, satu implementasi yang dominan . Borland mendefinisikan Pascal dan Microsoft mendefinisikan C # terlepas dari apa yang ANSI dan ECMA katakan.
dan04
4
Kode C, C ++, atau Fortran mengalami crash di bawah optimisasi tinggi jauh lebih sering salah memasukkan kode daripada bug penyusun. Saya sangat sering bekerja dengan kompiler baru dan pra-rilis, sering untuk perangkat keras yang sangat baru, dan melihat kegagalan terkait optimasi cukup teratur. Karena bahasa-bahasa ini memiliki gagasan tentang perilaku yang tidak terdefinisi dan tidak menentukan penanganan program yang tidak sesuai, kita harus memeriksa crash dengan sangat hati-hati, yang pada akhirnya menentang perakitan. Dalam 80-90% kasus, kode aplikasi salah, dan bukan kompiler.
Phil Miller
14

Kompiler memiliki beberapa properti yang mengarah pada kebenarannya:

  • Domain ini sangat terkenal, dan diteliti. Masalahnya didefinisikan dengan baik, dan solusi yang ditawarkan didefinisikan dengan baik.
  • Pengujian otomatis cukup untuk membuktikan kompiler bekerja dengan benar
  • Compiler memiliki tes unit yang sangat luas, biasanya publik, otomatis dan, yang telah terakumulasi dari waktu ke waktu untuk mencakup lebih banyak ruang kesalahan daripada untuk sebagian besar program lain
  • Compiler memiliki jumlah bola mata yang sangat besar menyaksikan hasilnya
blueberryfields
sumber
2
Juga dalam banyak kasus kodenya sudah tua, GCC sudah lebih dari 20 tahun, seperti banyak yang lainnya, jadi banyak bug telah dikerjakan dalam jangka waktu yang lama.
Zachary K
13

Kami menggunakan kompiler setiap hari

... dan bagaimana mereka membuat kompiler sangat dapat diandalkan?

Mereka tidak melakukannya. Kami lakukan. Karena setiap orang menggunakannya setiap saat, bug ditemukan dengan cepat.

Ini adalah permainan angka. Karena kompiler terbiasa dengan pervasif, kemungkinan besar bug apa pun akan dipicu oleh seseorang, tetapi karena ada sejumlah besar pengguna, sangat kecil kemungkinannya bahwa seseorang akan menjadi Anda secara khusus.

Jadi, itu tergantung pada sudut pandang Anda: di semua pengguna, kompiler buggy. Tetapi sangat mungkin bahwa orang lain akan telah mengkompilasi kode yang serupa sebelum Anda melakukannya, jadi jika mereka adalah bug, itu akan mengenai mereka, bukan Anda, jadi dari sudut pandang pribadi Anda , sepertinya bug itu adalah tidak pernah ada.

Tentu saja, di atas itu, Anda dapat menambahkan semua jawaban lain di sini: kompiler diteliti dengan baik, dipahami dengan baik. Ada mitos bahwa mereka sulit untuk menulis, yang berarti bahwa hanya programmer yang sangat pintar, sangat baik yang benar-benar mencoba untuk menulisnya, dan ekstra hati-hati ketika melakukannya. Mereka umumnya mudah untuk diuji, dan mudah untuk stress test atau fuzz test. Pengguna kompiler cenderung menjadi programmer ahli sendiri, yang mengarah ke laporan bug berkualitas tinggi. Dan sebaliknya: penulis kompiler cenderung menjadi pengguna kompiler mereka sendiri.

Jörg W Mittag
sumber
11

Selain semua jawaban yang sudah, saya ingin menambahkan:

Saya percaya banyak kali, para penjual makan makanan anjing mereka sendiri. Artinya, mereka menulis kompiler dalam diri mereka sendiri.

DevSolo
sumber
7

Saya sering mengalami bug kompiler.

Anda dapat menemukannya di sudut yang lebih gelap di mana ada lebih sedikit penguji. Misalnya, untuk menemukan bug di GCC Anda harus mencoba:

  • Bangun kompiler silang. Anda akan menemukan lusinan bug di skrip configure dan build GCC. Beberapa menghasilkan kegagalan build selama kompilasi GCC dan yang lainnya akan mengakibatkan kegagalan cross-compiler untuk membangun executable yang berfungsi.
  • Buat versi Itanium dari GCC menggunakan profil-bootstrap. Beberapa kali terakhir saya mencoba ini pada GCC 4.4 dan 4.5 gagal untuk menghasilkan pengendali pengecualian C ++ yang berfungsi. Bangunan yang tidak dioptimalkan berfungsi dengan baik. Sepertinya tidak ada yang tertarik untuk memperbaiki bug yang saya laporkan dan saya berhenti memperbaikinya sendiri setelah mencoba menggali apa yang melanggar spesifikasi memori asm GCC.
  • Cobalah membangun GCJ Anda sendiri dari hal-hal terbaru tanpa mengikuti skrip distro build. Saya menantang Anda.
Zan Lynx
sumber
Kami menemukan banyak masalah dengan IA64 (Itanium). Kami tidak memiliki banyak pelanggan untuk platform itu, jadi mengurangi tingkat optimisasi adalah perbaikan bug kami yang biasa. Ini kembali ke jawaban lain, kompiler untuk bahasa populer untuk arsitektur populer biasanya memiliki paparan pengguna yang cukup dan cukup dukungan untuk menjadi cukup baik, tetapi ketika Anda pergi ke arsitektur yang kurang populer dan / atau bahasa Anda harus mengharapkan keandalan untuk menderita.
Omega Centauri
@ Omega: Memotong kembali optimasi tampaknya seperti yang dilakukan semua orang. Sayangnya, Itanium membutuhkan kompiler beroptimalisasi tinggi agar dapat bekerja dengan baik. Oh well ...
Zan Lynx
Aku mendengarmu. Terus terang arsitektur sudah usang ketika keluar, untungnya AMD memaksa Intels tangan dengan x86-64 (yang menghina banyak kutil tidak begitu buruk). Jika Anda dapat memecah file sumber Anda, Anda mungkin dapat mengisolasi jika masalahnya adalah dan menemukan solusinya. Itulah yang kami lakukan jika ini adalah platform penting, tetapi untuk IA64, tidak.
Omega Centauri
@ Omega: Sayangnya, saya sangat suka Itanium. Ini arsitektur yang indah. Saya menganggap x86 dan x86-64 sudah usang tetapi tentu saja mereka tidak akan pernah mati.
Zan Lynx
X86 agak aneh. Mereka terus menambahkan barang baru ke dalamnya, sehingga tumbuh satu kutil pada satu waktu. Tapi, mesin eksekusi yang tidak sesuai berfungsi dengan baik, dan SSE => AVX yang baru menyediakan beberapa kemampuan nyata bagi mereka yang mau membuat kode untuk itu. Memang ada banyak transistor yang dikhususkan untuk melakukan hal-hal semi-usang, tapi itu harga yang harus dibayar untuk kompatibilitas warisan.
Omega Centauri
5

Beberapa alasan:

  • Penulis kompiler " makan makanan anjing mereka sendiri ".
  • Kompiler didasarkan pada prinsip - prinsip CS yang dipahami dengan baik .
  • Kompiler dibuat dengan spesifikasi yang sangat jelas .
  • Kompiler diuji .
  • Kompiler tidak selalu sangat andal .
Kramii Reinstate Monica
sumber
4

Mereka biasanya sangat bagus di -O0. Bahkan jika kami mencurigai bug kompiler, kami membandingkan -O0 versus level apa pun yang kami coba gunakan. Level optimisasi yang lebih tinggi cocok dengan risiko yang lebih besar. Beberapa bahkan sengaja melakukannya, dan diberi label seperti itu dalam dokumentasi. Saya telah menemukan banyak sekali (setidaknya seratus selama waktu saya), tetapi mereka menjadi jauh lebih jarang baru-baru ini. Namun demikian dalam mengejar angka-angka specmark yang baik (atau tolok ukur lain yang penting untuk pemasaran), godaan untuk mendorong batasan itu besar. Kami memiliki masalah beberapa tahun yang lalu di mana vendor (untuk tidak disebutkan namanya) memutuskan untuk melakukan pelanggaran terhadap tanda kurung default-lebih daripada beberapa opsi kompilasi yang diberi label dengan jelas.

Mungkin sulit untuk mendiagnosis kesalahan kompiler versus mengatakan referensi memori yang tersesat, kompilasi ulang dengan opsi yang berbeda mungkin hanya memperebutkan posisi relatif dari objek data dalam memori, sehingga Anda tidak tahu apakah itu Heisenbug kode sumber Anda, atau buggy penyusun. Juga banyak optimasi membuat perubahan yang sah dalam urutan operasi, atau bahkan penyederhanaan aljabar untuk aljabar Anda, dan ini akan memiliki sifat yang berbeda sehubungan dengan pembulatan titik mengambang dan under / overflow. Sulit untuk memisahkan efek ini dari bug NYATA. Komputasi floating point hard core sulit karena alasan ini, karena bug dan kepekaan numerik seringkali tidak mudah diurai.

Omega Centauri
sumber
4

Bug kompiler tidak terlalu langka. Kasus yang paling umum adalah bagi kompilator untuk melaporkan kesalahan pada kode yang harus diterima, atau bagi kompiler untuk menerima kode yang seharusnya ditolak.

kevin cline
sumber
sayangnya kita tidak dapat melihat bug kelas kedua: kompilasi kode = semuanya baik-baik saja. Jadi mungkin setengah bug (dengan asumsi rasio split 50-50 antara dua kelas bug) tidak ditemukan oleh orang-orang tetapi dengan rata-rata tes unit kompiler
Gianluca Ghettini
3

Yap, saya menemukan bug di kompiler ASP.NET baru kemarin:

Saat Anda menggunakan model yang sangat diketik dalam tampilan, ada batasan berapa banyak parameter yang dapat berisi template. Jelas tidak dapat mengambil lebih dari 4 parameter templat, sehingga kedua contoh di bawah ini membuatnya terlalu banyak untuk ditangani oleh kompiler:

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

Tidak akan mengkompilasi apa adanya tetapi akan jika type5dihapus.

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

Akan dikompilasi jika type4dihapus.

Catatan yang System.Tuplememiliki banyak kelebihan dan bisa memakan hingga 16 parameter (ini gila, saya tahu).

pengguna8685
sumber
3

Pernahkah Anda menemukan bug di kompiler itu sendiri? Apa itu dan bagaimana Anda menyadari masalahnya ada di kompiler itu sendiri?

Ya!

Dua yang paling berkesan adalah dua yang pertama saya temui. Mereka berdua di kompiler Lightspeed C untuk 680x0 Mac sekitar 1985-7.

Yang pertama adalah di mana, dalam beberapa keadaan, operator postincrement integer tidak melakukan apa pun - dengan kata lain, dalam potongan kode tertentu, "i ++" sama sekali tidak melakukan apa pun untuk "i". Saya mencabut rambut saya sampai saya melihat pembongkaran. Lalu saya hanya melakukan peningkatan dengan cara yang berbeda, dan mengirimkan laporan bug.

Yang kedua sedikit lebih rumit, dan benar-benar sebuah "fitur" yang dianggap salah. Mac awal memiliki sistem yang rumit untuk melakukan operasi disk tingkat rendah. Untuk beberapa alasan saya tidak pernah mengerti - mungkin ada hubungannya dengan membuat executable yang lebih kecil - daripada kompiler hanya menghasilkan instruksi operasi disk di tempat dalam kode objek, kompiler Lightspeed akan memanggil fungsi internal, yang pada saat runtime menghasilkan operasi disk instruksi di tumpukan dan melompat ke sana.

Itu bekerja sangat baik pada 68000 CPU, tetapi ketika Anda menjalankan kode yang sama pada CPU 68020, itu sering melakukan hal-hal aneh. Ternyata fitur baru dari 68020 adalah instruksi primitif 256-byte cache instruksi. Ini adalah hari-hari awal dengan cache CPU, itu tidak berpendapat bahwa cache "kotor" dan perlu diisi ulang; Saya kira para perancang CPU di Motorola tidak memikirkan kode modifikasi diri. Jadi, jika Anda melakukan dua operasi disk yang cukup berdekatan dalam urutan eksekusi Anda, dan runtime Lightspeed membuat instruksi aktual di lokasi yang sama pada stack, CPU akan keliru mengira itu memiliki cache instruksi yang hit dan menjalankan operasi disk pertama dua kali.

Sekali lagi, mencari tahu mengambil beberapa penggalian dengan disassembler, dan banyak langkah dalam debugger tingkat rendah. Solusi saya adalah untuk mengawali setiap operasi disk dengan panggilan ke fungsi yang melakukan 256 "NOP" instruksi, yang membanjiri (dan dengan demikian membersihkan) cache instruksi.

Lebih dari 25 tahun sejak itu, saya melihat semakin sedikit bug penyusun dari waktu ke waktu. Saya pikir ada beberapa alasan untuk itu:

  • Ada satu set tes validasi yang terus meningkat untuk kompiler.
  • Kompiler modern biasanya dibagi menjadi dua bagian atau lebih, yang salah satunya menghasilkan kode bebas platform (mis. LLVM menargetkan apa yang Anda anggap sebagai CPU imajiner), dan yang lain menerjemahkannya menjadi instruksi untuk perangkat keras target Anda yang sebenarnya. Dalam kompiler multi-platform, bagian pertama digunakan di mana-mana, sehingga mendapat banyak pengujian di dunia nyata.
Bob Murphy
sumber
Salah satu alasan untuk menghindari kode modifikasi diri.
Technophile
3

Ditemukan kesalahan mencolok di Turbo Pascal 5,5 tahun yang lalu. Galat hadir dalam versi kompiler sebelumnya (5.0) maupun versi (6.0) berikutnya. Dan yang seharusnya mudah untuk diuji, karena itu bukan cornercase sama sekali (hanya panggilan yang tidak biasa digunakan).

Secara umum, tentu pembangun kompiler komersial (daripada proyek hobi) akan memiliki QA yang sangat luas dan prosedur pengujian di tempat. Mereka tahu kompiler mereka adalah proyek andalan mereka dan bahwa kelemahan akan terlihat sangat buruk pada mereka, lebih buruk daripada yang mereka lihat pada perusahaan lain yang membuat sebagian besar produk lainnya. Pengembang perangkat lunak adalah kelompok yang tidak termaafkan, pemasok alat kami mengecewakan kami, kami cenderung mencari alternatif daripada menunggu perbaikan dari pemasok, dan kami sangat mungkin untuk mengomunikasikan fakta itu kepada rekan-rekan kami yang mungkin mengikuti kami contoh. Di banyak industri lain yang tidak demikian, sehingga potensi kerugian bagi pembuat kompiler sebagai akibat dari bug serius jauh lebih besar daripada yang dikatakan pembuat perangkat lunak video editing.

jwenting
sumber
2

Ketika perilaku perangkat lunak Anda berbeda ketika dikompilasi dengan -O0 dan dengan -O2, maka Anda telah menemukan bug kompilator.

Ketika perilaku perangkat lunak Anda hanya berbeda dari yang Anda harapkan, maka kemungkinan bug tersebut ada dalam kode Anda.

mouviciel
sumber
8
Belum tentu. Dalam C dan C ++, ada sejumlah perilaku yang tidak ditentukan dan tidak jelas yang mengganggu, dan itu dapat bervariasi berdasarkan tingkat atau fase optimasi bulan atau pergerakan indeks Dow Jones. Tes itu bekerja dalam bahasa yang didefinisikan lebih ketat.
David Thornley
2

Bug penyusun terjadi, tetapi Anda cenderung menemukannya di sudut aneh ...

Ada bug aneh di kompiler Digital Equipment Corporation VAX VMS C pada 1990-an

(Saya mengenakan bawang di ikat pinggang saya, seperti halnya fashion pada saat itu)

Titik koma asing di mana saja sebelum loop for akan dikompilasi sebagai tubuh loop for.

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

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

Pada kompiler yang dimaksud, loop dijalankan hanya sekali.

ia melihat

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

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

  {
     puts("hello");
  }
}

Itu menghabiskan banyak waktu.

Versi lama dari kompiler PIC C yang kami (gunakan) pada pengalaman kerja siswa tidak dapat menghasilkan kode yang menggunakan interupsi prioritas tinggi dengan benar. Anda harus menunggu 2-3 tahun dan memutakhirkan.

Kompiler MSVC 6 memiliki bug yang bagus di tautan, itu akan segmentasi kesalahan dan mati dari waktu ke waktu tanpa alasan. Bangunan bersih umumnya diperbaiki (tapi tidak selalu mendesah ).

Tim Williscroft
sumber
2

Di beberapa domain, seperti perangkat lunak avionik, ada persyaratan sertifikasi yang sangat tinggi, pada kode dan perangkat keras, serta pada kompiler. Tentang bagian terakhir ini, ada proyek yang bertujuan untuk membuat kompiler C yang terverifikasi secara formal, yang disebut Compcert . Secara teori, kompiler semacam ini dapat diandalkan karena mereka datang.

Axel
sumber
1

Saya telah melihat beberapa bug penyusun, melaporkan sendiri beberapa (khususnya, dalam F #).

Yang mengatakan, saya pikir bug kompiler jarang terjadi karena orang yang menulis kompiler pada umumnya sangat nyaman dengan konsep ketat ilmu komputer yang membuat mereka benar-benar sadar tentang implikasi matematis dari kode.

Sebagian besar dari mereka mungkin sangat akrab dengan hal-hal seperti kalkulus lambda, verifikasi formal, semantik denotasi, dll. - hal-hal yang hanya bisa dipahami oleh programmer biasa.

Juga, biasanya ada pemetaan yang cukup mudah dari input ke output dalam kompiler, jadi debugging bahasa pemrograman mungkin jauh lebih mudah daripada debugging, katakanlah, mesin blog.

Rei Miyasaka
sumber
1

Saya menemukan bug di compiler C # belum lama ini, Anda dapat melihat bagaimana Eric Lippert (yang ada di tim desain C #) menemukan apa bug itu di sini .

Selain jawaban yang sudah diberikan, saya ingin menambahkan beberapa hal lagi. Desainer kompiler seringkali merupakan programmer yang sangat baik. Compiler sangat penting: kebanyakan pemrograman dilakukan dengan menggunakan kompiler, jadi sangat penting kompiler berkualitas tinggi. Oleh karena itu, demi kepentingan terbaik perusahaan membuat kompiler untuk menempatkan orang-orang terbaik mereka di atasnya (atau setidaknya, yang sangat bagus: yang terbaik mungkin tidak suka desain kompiler). Microsoft sangat ingin kompiler C dan C ++ mereka bekerja dengan baik, atau perusahaan lain tidak dapat melakukan pekerjaan mereka.

Juga, jika Anda sedang membangun kompiler yang sangat kompleks, Anda tidak bisa hanya meretasnya bersama. Logika di balik kompiler sangat kompleks dan mudah diformalkan. Oleh karena itu, program-program ini akan sering dibangun dengan cara yang sangat 'kuat' dan generik, yang cenderung menghasilkan lebih sedikit bug.

Alex ten Brink
sumber