Apa yang menghentikan C dari kompilasi / interpretasi / JIT'ed?

9

Java sering dipuji karena portabilitasnya yang luar biasa, yang saya anggap karena JVM. Pertanyaan saya adalah apa yang menghentikan C dari dikompilasi / ditafsirkan / JIT'ed .., jika demikian, C juga dapat ditulis sekali dan membuatnya bekerja pada perangkat apa pun yang Anda miliki. tapi ini bukan mekanisme populer untuk memproses program C.

Apa kerugian dari pemrosesan C dengan cara ini, juga apa kelebihan dari pemrosesan Java dengan cara ini dan tidak dikompilasi ke kode mesin, selain dari portabilitas tentu saja?

Bola Bulat
sumber
Pertanyaan Anda sudah memiliki beberapa jawaban yang sangat bagus di sini: stackoverflow.com/questions/3925947/…
Doc Brown
2
@delnan poin saya adalah bahwa "apa yang menghentikan C dari dikompilasi / ditafsirkan / JIT'ed" benar-benar kehilangan maknanya ketika bahasa dapat menargetkan mesin virtual yang memiliki JIT atau situasi di mana vm akan mengidentifikasi fitur yang hilang dalam perangkat keras dan mengkompilasi ulang kode untuk mencocokkan perangkat keras yang ada (seperti dengan OpenGL (ditulis dalam C) pada OSX untuk kartu grafis yang berbeda). Tidak, Anda tidak dapat mengambil sesuatu yang dikompilasi untuk menargetkan llvm pada satu mesin dan menjalankannya seperti pada prosesor lain. Tetapi baris yang dikompilasi / ditafsirkan / JIT bisa sangat kabur.
1
Java sering hyped untuk itu portabilitas menakjubkan. Ini portabel untuk sistem di mana JVM telah dikompilasi, yaitu, sistem yang JVM (ditulis dalam C) telah dikompilasi. Tidak ada yang mencegah penanganan kode C dengan cara yang sama, kecuali bahwa tidak ada yang melihat cukup manfaat dari melakukannya untuk membenarkan upaya.
Pete Becker
2
Saya bingung tentang bagian ini: "apa yang menghentikan C dari dikompilasi / [...]". Uh, tidak ada apa-apa?
Andres F.
1
Kompiler C sangat cepat akhir-akhir ini sehingga "make myprog.c; myprog" mungkin akan berjalan lebih cepat daripada kebanyakan penerjemah.
James Anderson

Jawaban:

18

C adalah apa yang saya sebut bahasa tingkat menengah. Tujuannya adalah untuk berfungsi sebagai "assembler tingkat sangat tinggi," itulah sebabnya ia bekerja dengan sangat baik sebagai target kompiler, dan mengapa ia merangkul portabilitas dengan baik.

Secara historis, penerjemah biasanya digunakan dengan bahasa tingkat tinggi, dalam konteks pemanggilan metode. Dalam bentuknya yang paling sederhana, seorang juru bahasa hanya mem-parsing setiap kata kunci dalam bahasa sumber bersama dengan token yang terkait, dan mengonversinya menjadi panggilan metode dan parameter. Dalam praktiknya, apa yang dilakukan sebagian besar penafsir adalah mengubah bahasa sumber menjadi representasi perantara, dan representasi itulah yang ditafsirkan.

Apa yang menghentikan C dari ditafsirkan atau Dipasangkan? Tidak ada. Tapi itu bukan raison d'être C.

Robert Harvey
sumber
6

Pertama-tama, perlu dicatat bahwa Sun's JVM ditulis dalam bahasa C. C adalah bahasa yang sangat populer ketika portabilitas diperlukan.

C bahasa adalah portable meskipun banyak C program yang tidak. Ini karena C tidak menempatkan banyak pembatasan pada programmer atau membuat banyak asumsi. Jika seorang programmer C ingin program-programnya menjadi portabel, ia harus menempatkan batasan-batasan itu pada dirinya sendiri.

Dalam praktiknya, itu sebenarnya tidak jauh lebih sulit daripada hidup dengan pembatasan yang memaksa Java pada Anda. Ini sebagian besar masalah menjadi sadar akan endianness Anda dan ukuran primitif, dan menggunakan perpustakaan portabel seperti GTK + bukan perpustakaan platform-spesifik.

Anda dapat membuat target GTK + dan kompiler C yang mendukung mesin virtual, bahkan mungkin JVM, dan mendapatkan kode yang ada untuk bekerja dengan sedikit perubahan. Bahkan, tanpa pengumpulan sampah, mesin virtual C mungkin akan jauh lebih sederhana. Namun, mengapa Anda mau?

Sebaliknya, kompilasi Java ke kode asli, juga bisa dilakukan. Pada dasarnya itulah yang dilakukan JIT. Namun, mengapa Anda mau? Saya yakin ada proyek kesayangan untuk melakukannya "hanya karena," tetapi tidak digunakan dengan serius.

Karl Bielefeldt
sumber
5

Kamu berkata:

Java sering dipuji karena portabilitasnya yang luar biasa, yang saya anggap karena JVM.

Dan di sana, dalam kalimat pertama, Anda salah. Java tidak portabel karena JVM. Java adalah portable, karena bahasa Java didefinisikan dengan cara yang tidak meninggalkan implementor kelonggaran dalam bagaimana suatu program dapat berperilaku.

Sebagai contoh, Java memiliki dua jenis "int" (menandatangani integer 32 bit) dan "panjang" (menandatangani integer 64 bit). C dan C ++ memiliki "int" (masuk setidaknya 16 bit), "panjang" (masuk setidaknya 32 bit) dan "panjang panjang" (masuk setidaknya 64 bit). Itu karena C seharusnya dijalankan pada banyak prosesor yang berbeda, dan memungkinkan mereka untuk berperilaku berbeda.

C dapat menentukan ukuran tetap untuk tipe ini. Jika sudah, maka prosesor 36 bit tidak bisa mengimplementasikan bahasa C. Dan mereka memang tidak bisa mengimplementasikan Java! Jadi C mengizinkan bahasa untuk bekerja dengan berbagai komputer yang berbeda. Tidak dapat dihindari bahwa ini memungkinkan pembuatan kode yang tidak portabel. Ini masalah bahasa.

gnasher729
sumber
Dimungkinkan untuk meniru aritmatika 32-bit pada mesin 36-bit DAN MENINGGAL hasil setiap operasi dengan 0xFFFFFFFF untuk memotongnya menjadi 32-bit. Jadi, mesin ini bisa mengimplementasikan Java, itu hanya akan lebih lambat daripada jika Java memperbolehkan tipe berbasis nonet.
dan04
4

Java sangat portabel terutama karena bahasa tersebut menargetkan Java Virtual Machine, yang, seperti namanya, bukan mesin nyata . Karena Anda dapat menerapkan Mesin Virtual pada arsitektur berbagai jenis mesin nyata, program berbasis JVM sangat portabel.

C, di sisi lain, secara khusus dirancang untuk dijalankan terhadap perangkat keras yang nyata, karena ia dibuat untuk tujuan spesifik menerapkan sistem operasi, yang membutuhkan akses perangkat keras penuh. Ini berarti bahwa kode C tidak terlalu portabel dengan desain , dan ketika porting program C dari satu platform ke yang lain, berbagai bagian yang khusus untuk arsitektur target perlu ditulis ulang ke satu derajat atau yang lain.

Mason Wheeler
sumber
7
C sangat portabel. Anda hanya perlu mengkompilasi ulang pada platform target, dan hindari beberapa bit yang secara khusus dan sengaja tidak portabel.
Robert Harvey
5
@RobertHarvey: ... seperti hal-hal mendasar seperti ukuran berbagai primitif? ;)
Mason Wheeler
2
Ya, hal-hal itu. Sangat disayangkan bahwa masalahnya ada, tetapi bahasanya sepenuhnya portabel dalam segala hal, dan ada cara untuk memastikan bahwa ukuran primitif bekerja pada semua platform.
Robert Harvey
3
@ RobertTarvey: Saya akan mengatakan C memungkinkan untuk menulis program portabel, tetapi tidak membuatnya mudah.
Doc Brown
2
@RobertHarvey: apakah Anda ingin memulai perang agama? ;-) Bahasa portabel favorit saya adalah Python.
Doc Brown
3

Sebenarnya ada versi C yang ditafsirkan , tetapi mereka sebagian besar dimaksudkan untuk digunakan untuk eksperimen cepat daripada sistem produksi.

Mereka tidak biasa, karena bagaimanapun, mengapa Anda menderita semua keistimewaan C jika tidak mendapatkan eksekusi kecil, cepat dan statis?

fortran
sumber
3

Secara teoritis C dan Java dapat dikompilasi ke kode asli, ditafsirkan, atau dikompilasi ke mesin virtual.

Alasan teknis bahwa C tidak dikompilasi ke mesin virtual, adalah bahwa tidak ada mesin virtual C standar .

Dan sepertinya tidak ada yang ingin mendefinisikan mesin C virtual, atau bahkan mengkompilasi ke mesin virtual Java (yang sangat mungkin). Mungkin karena tidak ada yang menggunakan C ingin kehilangan kecepatannya yang tak tertandingi. Mungkin juga karena C paling kuat dalam komunitas open source yang dapat dengan mudah melakukan portabilitas dengan mengkompilasi (mendistribusikan dan mengkompilasi ulang sumber dan mengeksekusi), sehingga mereka tidak merasa perlu untuk portabilitas eksekusi (mendistribusikan dan mengeksekusi biner) sebagai tertutup pengembang sumber lakukan.

cmaster - mengembalikan monica
sumber
1

Sebenarnya ini sudah selesai. Ada kompiler utama yang mendukung kompilasi ke LLVM (saya tahu dentang melakukannya, dan saya percaya gcc juga melakukannya). LLVM itu bisa JIT sama seperti kode Java dikompilasi ke bytecode yang JIT.

Namun, apa yang membuat java "cross platform" dibandingkan dengan C adalah bahwa Java memiliki pustaka runtime besar yang telah porting ke banyak platform. C secara eksplisit tidak mengikuti paradigma ini.

Cort Ammon
sumber
C dengan POSIX bisa sangat portabel (ke sistem POSIX), jika Anda membuat kode dengan hati-hati.
Basile Starynkevitch
0

Ada beberapa perbedaan utama antara Java dan C. Java diisolasi dari sistem operasi melalui mesin virtual java (JVM). JVM memisahkan sistem operasi dari program. Aplikasi java mungkin meminta JVM untuk sepotong memori, dan JVM kemudian meminta OS untuk memori itu. Ada banyak JVM untuk platform / sistem operasi yang berbeda. JVM adalah yang memungkinkan program java yang sama dijalankan pada platform yang berbeda.

Dengan C, tidak ada isolasi OS. Program C (biasanya) berjalan langsung di atas OS, membuat panggilan OS langsung. Ini membuat ikatan program C dengan platform / sistem operasi tertentu. Program non-sepele akan melakukan panggilan ke sistem operasi. Selain itu, program C dikompilasi menjadi kode mesin, yang khusus untuk perangkat keras. Program C yang dikompilasi untuk x86 tidak dapat langsung dijalankan pada prosesor ARM.

CurtisHx
sumber
1
Java dikompilasi ke dalam bytecode platform-agnostik yang dapat (secara teoritis, setidaknya) dijalankan oleh JVM pada platform apa pun. C dikompilasi ke dalam bahasa assembly untuk CPU apa pun yang Anda targetkan (jadi jika Anda menargetkan arsitektur x86, kompiler C akan membuat assembler x86, atau assembler amd64 jika Anda menargetkan arsitektur itu, atau assembler ARM, dll). Kemudian bahasa assembly diubah menjadi file objek (binary assembler, really), yang dihubungkan ke file executable (beberapa format berbeda, tergantung pada mesin target).
Craig
1
Tidak ada dalam Spesifikasi Bahasa Jawa yang mengatakan apa pun tentang JVM, dan pada kenyataannya, ada implementasi Java tanpa JVM. Di Android, program Java dijalankan pada Dalvik VM (sekarang usang) atau Android Runtime, ada implementasi Java untuk CLI, implementasi yang mengkompilasi ke ECMAScript, dan implementasi yang mengkompilasi ke kode asli. Ada kompiler C yang mengkompilasi ke JVM. Ada kompiler C yang mengkompilasi ke ECMAScript. Ada penerjemah C.
Jörg W Mittag