Apakah C diketik dengan kuat?

88

Mengutip Wikipedia :

Dua bahasa yang umum digunakan yang mendukung berbagai jenis konversi implisit adalah C dan C ++, dan terkadang diklaim bahwa ini adalah bahasa yang diketik lemah. Namun, yang lain berpendapat bahwa bahasa-bahasa ini memberikan batasan yang cukup tentang bagaimana operan dari jenis yang berbeda dapat dicampur, sehingga keduanya harus dianggap sebagai bahasa yang diketik dengan kuat.

Apakah ada jawaban yang lebih pasti?

Sydius
sumber
190
Bagi seorang programmer C mengetik yang kuat berarti menekan tombol lebih keras.
Dan Dyer
2
C berada di sisi lemah dalam kontinum pengetikan. Tetapi ada cukup banyak item di kedua sisi sehingga Anda dapat berdebat dengan cara apa pun. Saat Anda melakukannya, Anda mungkin juga bertanya (vi atau emacs, netbeans atau eclipse, dll.)
Cervo
4
Kondisi permainan di Wikipedia cukup buruk sehingga saya merasa harus mengedit beberapa halaman Wikipedia. Mungkin sekarang sudah lebih baik. Mungkin.
Norman Ramsey
40
Re: Dan komentar (untuk memberikan kredit di mana itu jatuh tempo) Buku Peter van der Linden "Ahli Pemrograman C" berisi baris berikut: "Sampai hari ini, banyak programmer C percaya bahwa 'mengetik yang kuat hanya berarti menggedor keyboard ekstra keras."
Alexandros Gezerlis
Pertanyaan yang sangat bagus !!!
Destructor

Jawaban:

154

"Diketik dengan kuat" dan "diketik dengan lemah" adalah istilah yang tidak memiliki arti teknis yang disepakati secara luas. Istilah yang memiliki arti yang jelas adalah

  • Diketik secara dinamis berarti bahwa jenis dilampirkan ke nilai pada waktu proses, dan upaya untuk mencampur nilai dari jenis yang berbeda dapat menyebabkan "kesalahan jenis waktu proses". Misalnya, jika dalam Skema Anda mencoba menambahkan satu ke true dengan menulis (+ 1 #t)ini akan menyebabkan kesalahan. Anda mengalami kesalahan hanya jika Anda mencoba menjalankan kode yang melanggar.

  • Diketik secara statis berarti bahwa tipe-tipe tersebut diperiksa pada waktu kompilasi, dan program yang tidak memiliki tipe statis ditolak oleh kompilator. Misalnya, jika di ML Anda mencoba menambahkan satu ke true dengan menulis 1 + true, program akan ditolak dengan pesan kesalahan (mungkin samar). Anda selalu mendapatkan kesalahan meskipun kode tersebut mungkin tidak akan pernah dijalankan.

Orang yang berbeda lebih memilih sistem yang berbeda sesuai dengan seberapa besar mereka menghargai fleksibilitas dan seberapa besar mereka khawatir tentang kesalahan waktu berjalan.

Kadang-kadang "diketik dengan kuat" digunakan secara longgar untuk mengartikan "diketik secara statis", dan "diketik dengan lemah" digunakan secara tidak benar untuk berarti "diketik secara dinamis". Penggunaan yang lebih baik untuk istilah "sangat diketik" adalah bahwa "Anda tidak dapat mengatasi atau menumbangkan sistem tipe", sedangkan "tipe lemah" berarti "ada celah dalam sistem tipe". Sebaliknya, kebanyakan bahasa dengan sistem tipe statis memiliki celah, sementara banyak bahasa dengan sistem tipe dinamis tidak memiliki celah.

Tak satu pun dari istilah-istilah ini terhubung dengan cara apa pun dengan jumlah konversi implisit yang tersedia dalam suatu bahasa.

Jika Anda ingin berbicara persis tentang bahasa pemrograman, sebaiknya hindari istilah "diketik dengan kuat" dan "diketik dengan lemah". Saya akan mengatakan bahwa C adalah bahasa yang diketik secara statis tetapi memiliki banyak celah. Salah satu celahnya adalah Anda dapat dengan bebas mentransmisikan jenis penunjuk apa pun ke jenis penunjuk lainnya. Anda juga dapat membuat celah antara dua jenis pilihan Anda dengan mendeklarasikan serikat C yang memiliki dua anggota, satu untuk setiap jenis yang dipermasalahkan.

Saya telah menulis lebih banyak tentang pengetikan statis dan dinamis di why-interpreted-langs-are-most-ducktyped-while-compiled-have-strong-mengetik .

Norman Ramsey
sumber
2
Dari mana Anda mendapatkan definisi yang Anda sarankan untuk pengetikan kuat / lemah (hal celah)?
Sydius
2
Mengapa Anda membutuhkan "celah" dalam lingkungan pengetikan yang dinamis?
Chris Conway
4
@Sydius: Dari menghabiskan sebagian besar waktu 20 tahun terakhir bergaul dengan orang-orang yang merancang, membangun, dan menganalisis bahasa pemrograman dan sistem tipe. Itu pekerjaan saya yang dibayar :-)
Norman Ramsey
@ Chris: Saya belum pernah melihat bahasa yang diketik secara dinamis dengan 'celah'. Penggunaan umum celah adalah untuk bekerja dengan sistem atau OS run-time, misalnya, mengambil alamat mentah dan mengubahnya menjadi penunjuk ke nilai bahasa yang berperilaku baik. Anda dapat melakukan ini dalam pengaturan dinamis tetapi saya tidak mengetahui upaya apa pun.
Norman Ramsey
1
@NormanRamsey Saya pikir Chris merujuk dengan pertanyaannya ke:whereas "weakly typed" means "there are loopholes in the type system
Nir Alfasi
23

Sulit untuk mengklasifikasikan setiap bahasa menjadi 'lemah' atau 'sangat' diketik - ini lebih merupakan sebuah kontinum. Namun, dibandingkan dengan bahasa lain, C diketik dengan cukup kuat. Setiap objek memiliki tipe waktu kompilasi, dan kompilator akan memberi tahu Anda (dengan lantang) jika Anda melakukan sesuatu dengan objek yang tipenya tidak memungkinkan Anda melakukannya. Misalnya, Anda tidak dapat memanggil fungsi dengan jenis parameter yang salah, mengakses struct / anggota union yang tidak ada, dll.

Namun ada beberapa kelemahan. Salah satu kelemahan utama adalah typecasts - mereka pada dasarnya mengatakan bahwa Anda akan menyia-nyiakan jenis objek, dan kompiler harus diam (bila bisa). void*juga merupakan kelemahan lainnya - ini adalah penunjuk umum ke jenis yang tidak diketahui, dan saat Anda menggunakannya, Anda harus ekstra hati-hati karena Anda melakukan hal yang benar. Kompilator tidak dapat secara statis memeriksa sebagian besar penggunaan void*. void*juga bisa diubah menjadi pointer ke tipe apa pun tanpa cast (hanya di C, bukan di C ++), yang merupakan kelemahan lain.

Adam Rosenfield
sumber
Jawaban bagus, meskipun "typecasts ... dan compiler harus diam" mengganggu saya. Sebuah typecast tidak seperti mematikan peringatan, itu sebenarnya mengubah interpretasi dari nilai yang direferensikan.
Tall Jeff
15
Anda bingung antara "statis" dan "kuat" dalam kaitannya dengan mengetik. Kedua konsep ini tidak bergantung satu sama lain.
bendin
1
Dennis Richie (penulis C) menyebut C 'diketik dengan kuat dan diperiksa dengan lemah'
TimZaman
11

Literatur tidak jelas tentang ini. Menurut saya, ketikan yang kuat bukanlah ya / tidak, ada berbagai tingkat pengetikan yang kuat.

Bahasa pemrograman memiliki spesifikasi bagaimana ia menjalankan program. Terkadang tidak jelas bagaimana mengeksekusi dengan program tertentu. Misalnya, program yang mencoba mengurangi string dari angka. Atau program yang membagi dengan nol. Ada beberapa cara untuk mengatasi kondisi tersebut. Beberapa bahasa memiliki aturan untuk menangani kesalahan ini (misalnya, mengeluarkan pengecualian). Bahasa lain tidak memiliki aturan untuk menghadapi situasi ini. Bahasa-bahasa tersebut umumnya memiliki sistem tipe untuk mencegah program kompilasi yang mengarah ke perilaku yang tidak ditentukan. Dan ada juga bahasa yang memiliki perilaku tidak ditentukan dan tidak memiliki sistem tipe untuk mencegah kesalahan ini pada waktu kompilasi (jika Anda menulis program yang mengenai perilaku tidak ditentukan, program itu mungkin meluncurkan misil).

Begitu:

Bahasa yang menentukan apa yang terjadi pada waktu proses dalam setiap kasus (seperti menambahkan angka ke string) disebut diketik secara dinamis. Bahasa yang mencegah menjalankan program dengan kesalahan pada waktu kompilasi diketik secara statis. Bahasa yang tidak menentukan apa yang terjadi dan juga tidak memiliki sistem tipe untuk mencegah kesalahan disebut ketikan lemah.

Jadi apakah Java diketik secara statis? Ya, karena sistem tipenya melarang pengurangan string dari angka. Tidak, karena ini memungkinkan Anda untuk membagi dengan nol. Anda dapat mencegah pembagian dengan nol pada waktu kompilasi dengan sistem tipe. Misalnya dengan membuat jenis bilangan yang tidak boleh nol (misalnya NonZeroInt), dan hanya memperbolehkan untuk membagi dengan bilangan yang memiliki jenis ini.

Jadi, apakah C diketik dengan kuat atau diketik lemah? C diketik dengan kuat karena sistem tipe melarang beberapa kesalahan tipe. Tapi itu diketik lemah dalam kasus lain ketika tidak ditentukan apa yang terjadi (dan sistem tipe tidak melindungi Anda).

Jules
sumber
Saya suka penyelarasan dinamis dan statis Anda sebagai bentuk kuat, vs lemah. Namun, saya tidak yakin saya mengerti maksud Anda tentang sistem yang diketik secara statis berhenti dibagi nol. Jika yang saya ketik secara statis intmendapatkan nilai dari pengguna atau argumen baris perintah atau file, tidak ada yang dapat dilakukan kompilator untuk menghentikannya menjadi nol!
Rikki
1
Ada sistem tipe statis yang mencegah hal ini, tetapi sebagian besar bahasa "diketik" secara lemah atau dinamis sehubungan dengan pembagian dengan nol, karena ini adalah perilaku yang tidak ditentukan (C) atau mereka mengeluarkan pengecualian (Java).
Jules
11

C dianggap tidak diketik dengan lemah, karena Anda dapat mengonversi tipe apa pun ke tipe lain melalui cast, tanpa kesalahan kompiler. Anda dapat membaca lebih lanjut tentang masalah tersebut di sini .

mipadi
sumber
2
wikipedia menyesatkan di sini. C diketik dengan kuat, tipe sangat valid dan kompilator akan muntah jika Anda salah, namun, C juga menyediakan fitur bagi Anda untuk melewati ini. Bandingkan dengan bahasa seperti BCPL yang hanya memiliki tipe 'byte'.
gbjbaanb
13
Ketikan yang lemah tidak berarti suatu bahasa tidak memiliki jenis apa pun, itu hanya berarti bahwa jenis dapat secara implisit dipaksakan dari satu jenis ke jenis lainnya. Bandingkan dengan Python, bahasa yang sangat diketik di mana Anda harus secara eksplisit mengonversi jenis dengan pemanggilan fungsi.
mipadi
apakah bisa mentransmisikan sesuatu di C juga menyebabkannya menjadi tipe yang lemah. ?? Saya memiliki keraguan ini untuk selamanya
Suraj Jain
8

C lebih kuat diketik daripada Javascript dan kurang kuat diketik daripada Ada.

Saya akan mengatakan itu jatuh lebih ke sisi kontinum yang diketik dengan kuat. tetapi orang lain mungkin tidak setuju (meskipun mereka salah).

Bagaimana dengan definitif?

Michael Burr
sumber
Itu adalah jawaban yang agak bercanda. Tapi uraikan kesalahannya.
Michael Burr
1
Javascript sangat diketik. Itu tidak diketik secara statis. Semua pemeriksaan jenis terjadi pada waktu proses (dinamis, bukan statis) tetapi pemeriksaan tersebut terjadi dan mencegah Anda dari merusak memori (salah satu aspek dari pengetikan yang kuat).
bendin
5
Nah, seperti yang ditunjukkan oleh jawaban Norm Ramsey yang sangat baik, "diketik dengan kuat" dan "diketik dengan lemah" bukanlah istilah yang didefinisikan dengan baik. Selain itu, selama Javascript diketik dengan kuat, beberapa orang mungkin percaya bahwa ("4" / ​​"2") sebagai ekspresi Javascript yang valid mungkin menunjukkan sebaliknya.
Michael Burr
5

C dianggap diketik secara statis (Anda tidak dapat mengubah variabel dari int menjadi float). Setelah variabel dideklarasikan, ia akan terjebak seperti itu.

Namun dikategorikan lemah karena tipenya bisa flip-flop.

Berapakah 0? '\ 0', FALSE, 0,0, dll ..

dalam banyak bahasa Anda tidak bisa mengatakan IF (variabel) karena kondisi hanya akan mengambil nilai boolean dari ekspresi boolean. Ini lebih diketik dengan kuat. Hal yang sama berlaku untuk berpindah antara karakter dan bilangan bulat.

pada dasarnya c memiliki dua tipe data sederhana utama, bilangan bulat dan bilangan floating point (meskipun berbagai presisi). Segala sesuatu yang lain boolean, enum (tidak sederhana tapi cocok), dll. Diimplementasikan sebagai salah satunya. Bahkan karakter pada dasarnya adalah bilangan bulat.

Bandingkan dengan bahasa lain yang memiliki tipe string, tipe enum yang hanya dapat ditetapkan ke nilai yang ditentukan, tipe boolean yang hanya ekspresi yang menghasilkan boolean atau true / false yang dapat digunakan.

Tapi Anda bisa membantah bahwa dibandingkan dengan Perl C sangat diketik. Jadi ini adalah salah satu argumen terkenal (vi vs emacs, linux vs windows, dll.). C # lebih kuat diketik daripada C. Pada dasarnya Anda bisa berdebat dengan cara apa pun. Dan jawaban Anda mungkin akan dua arah :) Juga beberapa buku teks / halaman web akan mengatakan C diketik dengan lemah, dan beberapa akan mengatakan C diketik dengan kuat. Jika Anda pergi ke wikipedia, entri C mengatakan "pengetikan sebagian lemah". Saya akan mengatakan dibandingkan dengan Python C diketik lemah. Jadi Python / C #, C, Perl pada kontinum.

Cervo
sumber
Tolong jelaskan alasan Anda bahwa Perl kurang diketik daripada C.
user51568
cetak "Pengujian" + 0 # perl akan melakukan 0; $ var = "string"; $ var = 1; $ var = 123,4; Variabel macam apa itu?
Cervo
Dalam C char * test = "testing"; printf (pengujian + 0); akan tetap berupa string, hanya saja di C index akan berubah jika bukannya nol saya menggunakan angka. Ini masih cukup lemah, tapi sedikit lebih kuat dari perl. tes char *; tes = 0; tes = 123,4; test = "c"; ... kompiler saya menghasilkan kesalahan
Cervo
kesalahan mengatakan bahwa pemeran diperlukan. Masih sedikit lebih kuat dari jenis pemeriksaan daripada Perl jadi pada kontinum saya harus mengatakan C lebih kuat diketik daripada Perl. Anda masih bisa pergi test = (char *) dan kemudian menggunakan 0, 123.4, 'C', dll .. Tapi itu adalah kesalahan untuk melakukannya.
Cervo
4

Banyak jawaban bagus di sini. Saya ingin mengemukakan poin penting dari Real World Haskell :

Penting untuk diketahui bahwa banyak komunitas bahasa memiliki definisi "tipe kuat" sendiri. Namun demikian, kami akan berbicara secara singkat dan dalam istilah luas tentang pengertian kekuatan dalam sistem tipe.

(menggunting)

Kembang api di sekitar sistem tipe berakar pada bahasa Inggris biasa, di mana orang melampirkan pengertian nilai pada kata "weak" dan "strong": kita biasanya menganggap kekuatan lebih baik daripada kelemahan. Lebih banyak lagi pemrogram yang berbicara bahasa Inggris biasa daripada jargon akademis, dan seringkali akademisi benar-benar melemparkan batu bata pada sistem jenis apa pun yang tidak sesuai dengan keinginan mereka. Hasilnya adalah hiburan Internet yang populer, perang api.

Jadi, lihat jawaban tentang C dan C ++, tetapi ingat bahwa 'kuat' dan 'lemah' tidak memetakan ke 'baik' dan 'buruk'.

ramping
sumber
4

Menurut Dennis Ritchie ( pencipta C ) dan Brian Kernighan, C bukanlah bahasa yang diketik dengan kuat. Baris berikut adalah dari buku Bahasa pemrograman C halaman 3 paragraf 5

C bukanlah bahasa yang diketik dengan kuat, tetapi seiring perkembangannya, pemeriksaan jenisnya telah diperkuat.

perkasaWOZ
sumber
3

Menurut saya, C / C ++ diketik dengan kuat. Jenis peretasan yang memungkinkan jenis untuk diubah (void *) ada karena kedekatan C dengan mesin. Dengan kata lain, Anda dapat memanggil perintah assembler dari Pascal dan memanipulasi pointer dan Pascal masih dianggap sebagai bahasa yang diketik dengan kuat. Anda dapat memanggil assembler dan C dapat dieksekusi dari Java melalui JNI tetapi itu tidak membuat Java diketik dengan lemah.

C hanya memiliki assembler "tertanam" di dalamnya dengan petunjuk mentah dan semacamnya.

mannicken
sumber
3

Istilah yang diketik dengan kuat tidak memiliki definisi yang disepakati. Oleh karena itu, kecuali Anda mendefinisikan apa yang Anda maksud dengan "diketik dengan kuat", tidak mungkin menjawab pertanyaan Anda.

Dalam pengalaman saya, istilah "diketik dengan kuat" dan "diketik dengan lemah" digunakan secara eksklusif oleh troll, karena kurangnya definisi memungkinkan para troll untuk mendefinisikan ulang mereka di tengah argumen agar sesuai dengan agenda mereka. Selain untuk memulai flamewars, istilah-istilah ini sangat tidak berguna.

Anda mungkin juga ingin melihat apa saja aspek kunci dari bahasa yang diketik dengan kuat? di sini, di StackOverflow.

Jörg W Mittag
sumber
3
Saya tidak setuju. "Diketik dengan kuat" berarti dimungkinkan untuk menentukan tipe data suatu nilai, dan hanya operasi yang sesuai untuk jenis itu yang diperbolehkan. Alamat "secara dinamis" dan "statis" saat penentuan itu dapat dibuat.
joel.neely
2
Anda benar- benar menyadari ironi mencoba membantah pernyataan bahwa tidak ada definisi yang disepakati dengan memperkenalkan definisi lain, bukan?
Jörg W Mittag
1
@Jorg: Tidak mencoba memperkenalkan yang lain; hanya menyatakan yang biasa digunakan di lingkaran tempat saya pindah.
joel.neely
1

Ada kontinum dengan beberapa jalan paralel antara "diketik lemah" dan "diketik dengan kuat", dua istilah yang bahkan tidak didefinisikan dengan baik.

C diketik secara statis , di mana kompilator mengetahui tipe yang dideklarasikan dari setiap variabel lokal dan anggota struct.

Bahasa yang diketik secara dinamis mungkin masih diketik dengan kuat, jika setiap objek memiliki tipe tertentu tetapi tidak ada cara bagi kompilator untuk mengetahui tipe itu.

yfeldblum
sumber
0

Apa alasan pertanyaan Anda? Alasan saya bertanya adalah ini semacam perbedaan kecil dan penggunaan khusus "diketik dengan kuat" Anda mungkin memerlukan klarifikasi lebih atau kurang. Saya pasti akan mengatakan bahwa Java dan bahasa lain memiliki batasan yang lebih ketat pada jenis percakapan implisit.

BobbyShaftoe
sumber
Sebagian besar rasa ingin tahu, tetapi saya melamar posisi C, dan ingin tahu apakah mereka menanyai saya tentang hal itu.
Sydius
Maka mungkin jawaban yang lebih panjang yang memberikan nuansa "diketik dengan kuat" adalah pendekatan terbaik daripada hanya mengatakan "ya" atau "tidak".
BobbyShaftoe
0

Sulit untuk memberikan jawaban yang konkret jika tidak ada definisi konkret tentang "diketik dengan kuat". Saya akan mengatakan bahwa C diketik dengan kuat di setiap variabel dan setiap ekspresi memiliki tipe tetapi diketik lemah yang memungkinkan Anda untuk mengubah jenis menggunakan gips dan menafsirkan kembali representasi satu jenis sebagai jenis lainnya.

Robert Gamble
sumber
Ada def resmi. untuk diketik dengan kuat . Dikatakan bahwa sys. adalah ST ketika seseorang menjamin bahwa tidak ada kesalahan jenis waktu berjalan. Contoh: ML, Haskell. Ini berguna untuk membuat sistem menghilangkan tag tipe di dalam objek, dan bagaimanapun menerapkan operator pada tipe yang benar. Karena kita tahu sebelum eksekusi bahwa tidak diperlukan tag di objek. Karena C memiliki akses cast dan pointer ke memo sewenang-wenang, C tidak st
juga
0

Saya akan mengatakan bahwa C diketik sekuat kompiler / platform Anda. Misalnya, jika Anda membangun di atas platform yang ketat, dereferensikan jenis penunjuk yang diberi hukuman kemungkinan besar akan rusak:

Sekarang, jika Anda memberi tahu kompiler untuk melewati aliasing ketat, ini bukan masalah, tetapi tidak terlalu portabel. Jadi, dalam pengertian itu, mendorong batas-batas bahasa itu mungkin tetapi mungkin bukan ide terbaik. Itu melangkah lebih jauh dari casting biasa, yaitu casting int selama dan benar-benar menunjukkan salah satu kemungkinan jebakan void.

Jadi, saya akan mengatakan C pada dasarnya diketik dengan ketat, tetapi berbagai penyusunnya menganggap bahwa programmer paling tahu dan memungkinkan beberapa fleksibilitas. Ini sangat bergantung pada kompiler, beberapa tidak akan menangkap potensi oops tersebut. Jadi dalam hal ini, penyusun pilihan benar-benar berperan saat menjawab pertanyaan. Apa yang benar sering kali berbeda dari apa yang kompilator Anda perkenankan untuk Anda gunakan.

Tim Pos
sumber
0

c diketik lemah, b tidak diketik.

plan9assembler
sumber
Jawaban ini terlalu pendek jika diberikan pertanyaan.
Keith Pinson
-1

Tidak diketik dengan kuat.

Pertimbangkan apa yang dikatakan prototipe fungsi berikut tentang tipe data dari argumen:

Tidak ada. Jadi saya menyarankan agar pengetikan yang kuat tidak berlaku di sini.

joel.neely
sumber
Hah? Ini memberi tahu Anda bahwa ada int, diikuti dengan karakter, diikuti oleh sejumlah argumen jenis apa pun. Itu bukan "tidak ada".
Lawrence Dol
... tidak memberi tahu Anda tentang jenis argumen yang diberikan. Memang benar bahwa jenis fungsinya sendiri sudah tahu. Itulah yang dikatakan Software Monkey.
Johannes Schaub - litb
"Argumen dalam jumlah berapa pun" itulah yang saya bicarakan. Sebuah rantai hanya sekuat mata rantai terlemahnya.
joel.neely
-3

Saya akan mengatakan itu adalah tipe yang kuat karena setiap ekspresi memiliki tipe yang bukan merupakan fungsi dari nilainya; ei itu dapat diketahui sebelum runtime.

OTOH Saya tidak yakin bahwa deskripsi yang diketik dengan benar adalah yang benar. Satu-satunya klaim yang lebih kuat yang dapat saya lihat alasan pembuatan bahasa adalah jaminan bahwa Anda tidak dapat menumbangkan sistem tipe pada saat runtime melalui interpretasi ulang tipe cast, unions, panggilan ke bahasa lain, pointer, bahasa assembly, dll. Bahasa seperti ini ada tetapi sangat lumpuh sehingga tampaknya tidak terlalu menarik bagi pemrogram di luar jaminan tinggi dan akademisi. Seperti yang ditunjukkan oleh seseorang, untuk benar-benar melakukan itu dengan benar, Anda mulai perlu memiliki tipe suka nonZeroIntdan yang lainnya. Yuck.

BCS
sumber
3
Apa yang tidak? Definisi saya tentang sangat diketik atau C?
BCS