Fitur bahasa tertentu, bahkan jika itu adalah tambahan, dapat mengubah keseluruhan cara bahasa praktis perlu digunakan. Sebagai satu contoh, pertimbangkan kasus ini:
lock_mutex(&mutex);
// call some functions
...
unlock_mutex(&mutex);
Jika kode di atas melibatkan fungsi pemanggilan yang diimplementasikan dalam C ++, kita mungkin berada dalam masalah, karena salah satu dari pemanggilan fungsi itu mungkin dilemparkan dan kita tidak akan pernah membuka kunci di jalur luar biasa tersebut.
Destructors tidak lagi dalam bidang kenyamanan untuk membantu programmer menghindari lupa untuk melepaskan / sumber daya gratis pada saat itu. RAII menjadi persyaratan praktis karena tidak layak secara manusiawi untuk mengantisipasi setiap baris kode yang dapat memberikan contoh-contoh non-sepele (belum lagi bahwa baris-baris itu mungkin tidak dibuang sekarang tetapi mungkin nanti dengan perubahan). Ambil contoh lain:
void f(const Foo* f1)
{
Foo f2;
memcpy(&f2, f1, sizeof f2);
...
}
Kode seperti itu, walaupun umumnya tidak berbahaya di C, seperti api neraka yang menguasai kekacauan di C ++, karena memcpy
bulldozes atas bit dan byte dari objek-objek ini dan mem-bypass hal-hal seperti copy constructor. Fungsi seperti suka memset
, realloc
, memcpy
, dll, sementara alat sehari-hari di kalangan pengembang C digunakan untuk melihat hal-hal dengan cara yang agak homogen bit dan byte dalam memori, tidak harmonis dengan sistem tipe yang lebih kompleks dan lebih kaya dari C ++. C ++ mendorong tampilan yang lebih abstrak dari tipe yang ditentukan pengguna.
Jadi hal-hal seperti ini tidak lagi memungkinkan untuk C ++, oleh siapa pun yang ingin menggunakannya dengan benar, untuk melihatnya sebagai "superset" belaka dari C. Bahasa-bahasa ini membutuhkan pola pikir, disiplin, dan cara berpikir yang sangat berbeda untuk menggunakan yang paling efektif .
Saya tidak berada di kamp yang melihat C ++ sebagai yang lebih baik dalam segala hal, dan sebenarnya sebagian besar lib pihak ketiga favorit saya adalah perpustakaan C untuk beberapa alasan. Saya tidak tahu persis mengapa tetapi lib C cenderung lebih minimalis di alam (mungkin karena tidak adanya sistem tipe kaya membuat pengembang lebih fokus pada menyediakan fungsionalitas minimal yang diperlukan tanpa membangun beberapa abstraksi yang besar dan berlapis), meskipun saya sering berakhir hanya menempatkan pembungkus C ++ di sekitar mereka untuk menyederhanakan dan menyesuaikan penggunaannya untuk tujuan saya, tetapi sifat minimalis lebih disukai bagi saya bahkan ketika melakukan itu. Saya sangat menyukai minimalis sebagai fitur menarik dari perpustakaan bagi mereka yang menggunakan waktu ekstra untuk mencari kualitas seperti itu, dan mungkin C cenderung mendorong itu,
Saya menyukai C ++ jauh lebih sering daripada tidak, tapi saya sebenarnya diharuskan menggunakan C API lebih sering untuk kompatibilitas biner terluas (dan untuk FFI), meskipun saya sering mengimplementasikannya dalam C ++ walaupun menggunakan C untuk header. Tapi kadang-kadang ketika Anda pergi tingkat yang sangat rendah, seperti ke tingkat pengalokasi memori atau struktur data tingkat yang sangat rendah (dan saya yakin ada contoh lebih lanjut di antara mereka yang melakukan pemrograman tertanam), kadang-kadang bisa membantu untuk menjadi dapat berasumsi bahwa tipe dan data yang Anda kerjakan tidak ada fitur tertentu seperti vtables, costructors, dan destructor, sehingga kami dapat memperlakukannya sebagai bit dan byte untuk diacak, disalin, bebaskan, realokasi. Untuk masalah tingkat rendah yang sangat khusus, terkadang dapat membantu untuk bekerja dengan sistem tipe yang jauh lebih sederhana yang disediakan C,
Klarifikasi
Satu komentar menarik di sini saya ingin menanggapi sedikit lebih mendalam (saya menemukan komentar di sini sangat ketat pada batas karakter):
memcpy(&f2, f1, sizeof f2);
juga "neraka berkuasa atas kekacauan" di C jika Foo memiliki petunjuk yang memiliki, atau bahkan lebih buruk, karena Anda juga tidak memiliki alat untuk menghadapinya.
Itu poin yang adil tetapi semua yang saya fokuskan terutama dengan fokus pada sistem tipe C ++ dan juga sehubungan dengan RAII. Salah satu alasan penggandaan byte-ray seperti itu memcpy
atau qsort
tipe fungsi yang kurang menimbulkan bahaya praktis di C adalah bahwa penghancuran dari f1
dan di f2
atas adalah eksplisit (jika mereka membutuhkan penghancuran non-sepele), sedangkan ketika penghancur bergerak ke dalam gambar. , mereka menjadi tersirat dan otomatis (seringkali dengan nilai bagus untuk pengembang). Itu belum lagi keadaan tersembunyi seperti vptrs dan sebagainya yang fungsi-fungsi seperti itu akan melibas. Jika f1
memiliki pointer danf2
dangkal menyalinnya dalam beberapa konteks sementara, maka itu tidak menimbulkan masalah jika kita tidak mencoba untuk secara eksplisit membebaskan mereka yang memiliki pointer kedua kalinya. Dengan C ++ itu adalah sesuatu yang kompiler akan secara otomatis ingin lakukan.
Dan itu menjadi lebih besar jika biasanya dalam C, " Jika Foo memiliki pointer", karena kesaksian yang diperlukan dengan manajemen sumber daya akan sering membuat sesuatu yang biasanya lebih sulit untuk diabaikan sedangkan dalam C ++, kita dapat membuat UDT tidak lagi sepele. constructible / destructible hanya dengan membuatnya menyimpan variabel anggota mana pun yang tidak sepele membangun / destructible (dengan cara yang umumnya sangat membantu, sekali lagi, tetapi tidak jika kita tergoda untuk menggunakan fungsi seperti memcpy
atau realloc
).
Poin utama saya adalah untuk tidak mencoba memperdebatkan manfaat dari kesaksian ini (saya akan mengatakan jika ada, mereka hampir selalu terbebani oleh kontra meningkatnya kemungkinan kesalahan manusia yang menyertainya), tetapi hanya untuk mengatakan bahwa fungsi seperti memcpy
dan memmove
dan qsort
dan memset
danrealloc
dan sebagainya tidak memiliki tempat dalam bahasa dengan UDT yang kaya fitur dan kemampuan seperti C ++. Meskipun mereka ada, saya pikir tidak akan terlalu diperdebatkan untuk mengatakan bahwa sebagian besar, pengembang C ++ yang luas akan bijaksana untuk menghindari fungsi seperti wabah, sedangkan ini adalah jenis fungsi yang sangat harian di C, dan saya d berpendapat bahwa mereka menimbulkan lebih sedikit masalah dalam C karena alasan sederhana bahwa sistem tipenya jauh lebih mendasar dan, mungkin "bodoh". Tipe C sinar-X dan memperlakukannya sebagai bit dan byte rentan kesalahan. Melakukan hal itu dalam C ++ bisa dibilang keliru karena fungsi-fungsi tersebut berjuang melawan fitur-fitur yang sangat mendasar dari bahasa dan apa yang didorongnya dari sistem tipe.
Itu sebenarnya daya tarik terbesar bagi saya C, bagaimanapun, khususnya dengan bagaimana hal itu terkait dengan interoperabilitas bahasa. Akan jauh, jauh lebih sulit untuk membuat sesuatu seperti C #'s FFI memahami sistem tipe penuh dan fitur bahasa C ++ ke konstruktor, destruktor, pengecualian, fungsi virtual, kelebihan fungsi / metode, kelebihan operator, kelebihan semua jenis pewarisan, dll. Dengan C itu adalah bahasa yang relatif bodoh yang telah menjadi agak standar sejauh API dengan cara yang banyak bahasa dapat impor langsung melalui FFI, atau secara tidak langsung melalui beberapa fungsi ekspor C API dalam bentuk yang diinginkan (mis: Java Native Interface ). Dan di situlah saya kebanyakan tidak punya pilihan selain menggunakan C, karena interoperabilitas bahasa merupakan persyaratan praktis dalam kasus kami (meskipun sering saya '
Tapi tahukah Anda, saya seorang pragmatis (atau setidaknya saya berusaha keras untuk menjadi). Jika C adalah bahasa yang paling kotor dan mengerikan, rawan kesalahan, dan jahat, beberapa rekan penggila C ++ saya mengklaimnya (dan saya menganggap diri saya penggemar C ++ kecuali bahwa entah bagaimana hal itu tidak mengarah pada kebencian C di pihak saya. ; sebaliknya itu memiliki efek sebaliknya pada saya untuk membuat saya menghargai kedua bahasa lebih baik dalam hal dan perbedaan mereka sendiri), maka saya berharap bahwa muncul di dunia nyata dalam bentuk beberapa buggiest dan leakiest dan produk dan perpustakaan yang tidak dapat diandalkan ditulis dalam C. Dan saya tidak menemukan itu. Saya suka Linux, saya suka Apache, Lua, zlib, saya menemukan OpenGL dapat ditoleransi karena warisan panjangnya terhadap persyaratan perangkat keras yang bergeser, Gimp, libpng, Kairo, dll. Setidaknya, apa pun rintangan yang ditimbulkan oleh bahasa, tampaknya tidak menimbulkan kemacetan sejauh menulis beberapa perpustakaan dan produk keren di tangan yang kompeten, dan hanya itulah yang saya minati. Jadi saya belum pernah menjadi tipe yang begitu tertarik pada yang paling bersemangat. perang bahasa, kecuali untuk membuat daya tarik pragmatis dan berkata, "Hei, ada hal-hal keren di luar sana! Mari kita belajar bagaimana mereka membuatnya dan mungkin ada pelajaran keren, tidak begitu spesifik dengan sifat bahasa yang idiomatik, yang dapat kita bawa kembali untuk bahasa apa pun yang kami gunakan. " :-D