Apakah saya cor hasil malloc?

Dalam pertanyaan, seseorang disarankan dalam komentar bahwa saya harus tidak cast hasil dari malloc, yaitu

int *sieve = malloc(sizeof(int) * length);

daripada:

int *sieve = (int *) malloc(sizeof(int) * length);

Mengapa hal ini bisa terjadi?

Mengomentari pertanyaan (2)
Larutan

No; anda don't cast hasilnya, karena:

  • Hal ini tidak perlu, seperti void * adalah secara otomatis dan aman dipromosikan ke lain jenis pointer dalam kasus ini.
  • Menambah kekacauan dengan kode, gips yang tidak sangat mudah untuk membaca (terutama jika pointer tipe lama).
  • Itu membuat anda mengulangi diri sendiri, yang umumnya buruk.
  • Dapat menyembunyikan kesalahan jika anda lupa untuk menyertakan <stdlib.h>. Hal ini dapat menyebabkan crash (atau, lebih buruk lagi, tidak penyebab kecelakaan sampai kemudian cara di beberapa benar-benar bagian yang berbeda dari kode). Pertimbangkan apa yang terjadi jika pointer dan bilangan bulat yang berbeda ukuran, kemudian anda're bersembunyi peringatan dengan casting dan mungkin kehilangan bit dari alamat kembali. Catatan: pada C99 fungsi implisit yang hilang dari C, dan titik ini adalah tidak relevan lagi karena ada's otomatis tidak ada asumsi yang dideklarasikan kembali fungsi int.

Sebagai klarifikasi, perhatikan bahwa saya mengatakan "anda don't cast" tidak "anda don't perlu untuk pemain". Dalam pendapat saya, itu's kegagalan untuk menyertakan pemain, bahkan jika anda sudah benar. Ada hanya tidak ada manfaat untuk melakukan hal itu, tetapi banyak dari potensi risiko, dan termasuk pemain menunjukkan bahwa anda don't tahu tentang risiko.

Perhatikan juga, sebagai komentator menunjukkan, bahwa di atas berbicara tentang lurus C, bukan C++. Saya sangat yakin dalam C dan C++ sebagai bahasa terpisah.

Untuk menambahkan lebih lanjut, kode anda sia-sia mengulangi jenis informasi (int) yang dapat menyebabkan kesalahan. It's baik untuk de-referensi pointer digunakan untuk menyimpan return value, untuk "lock" dua bersama-sama:

int *sieve = malloc(length * sizeof *sieve);

Ini juga bergerak panjang ke depan untuk meningkatkan visibilitas, dan tetes berlebihan kurung dengan ukuran; mereka hanya diperlukan ketika argumen adalah nama jenis. Banyak orang tampaknya tidak tahu (atau mengabaikan) ini, yang membuat kode mereka lebih verbose. Ingat: sizeof bukan fungsi! :)


Saat bergerak panjang untuk bagian depan mungkin meningkatkan visibilitas dalam beberapa kasus yang jarang terjadi, seseorang juga harus memperhatikan bahwa dalam kasus umum, itu harus lebih baik untuk menulis ekspresi seperti:

int *sieve = malloc(sizeof *sieve * length);

Karena menjaga sizeof pertama, dalam kasus ini, memastikan perkalian ini dilakukan dengan setidaknya size_t matematika.

Bandingkan: malloc(sizeof *saringan * panjang * lebar) vs malloc(panjang * lebar * sizeof *saringan) yang kedua mungkin meluap panjang * lebar ketika width dan panjang adalah jenis yang lebih kecil dari size_t.

Komentar (32)

Di C, anda don't perlu untuk melemparkan kembali nilai malloc. Pointer untuk membatalkan kembali oleh malloc otomatis dikonversi ke jenis yang tepat. Namun, jika anda ingin kode anda untuk compile dengan compiler C++, pemain yang dibutuhkan. Alternatif yang lebih disukai di kalangan masyarakat adalah dengan menggunakan kode berikut:

int *sieve = malloc(sizeof *sieve * length);

yang selain itu membebaskan anda dari keharusan untuk khawatir tentang mengubah sisi kanan dari ekspresi jika anda mengubah jenis saringan.

Gips yang buruk, karena orang-orang telah menunjukkan. Khusus pointer gips.

Komentar (8)

Anda do cast, karena:

  • Membuat kode anda lebih portabel antara C dan C++, dan JADI pengalaman menunjukkan, banyak programmer mengklaim mereka menulis di C ketika mereka benar-benar menulis di C++ (C plus lokal compiler ekstensi).
  • Kegagalan untuk melakukannya dapat menyembunyikan kesalahan: catatan semua JADI contoh membingungkan ketika menulis tipe * versus tipe **.
  • Ide yang membuat anda memperhatikan anda gagal untuk #include yang tepat header file merindukan hutan untuk pohon. It's sama dengan mengatakan "don't khawatir tentang fakta anda gagal untuk meminta compiler untuk mengeluh tentang tidak melihat prototipe -- yang sial stdlib.jam ini SEBENARNYA penting untuk diingat!"
  • Pasukan tambahan kognitif cross-check. Ini menempatkan (dugaan) tipe yang diinginkan tepat di sebelah aritmatika anda're lakukan untuk ukuran baku dari variabel tersebut. Saya yakin anda bisa melakukan BEGITU penelitian yang menunjukkan bahwa malloc() bug tertangkap jauh lebih cepat ketika ada's cor. Seperti halnya dengan pernyataan-pernyataan, penjelasan yang mengungkapkan maksud mengurangi bug.
  • Mengulangi diri dengan cara yang mesin dapat memeriksa sering bagus ide. Pada kenyataannya, bahwa's apa pernyataan ini, dan ini menggunakan cor adalah sebuah pernyataan. Pernyataan masih yang paling umum teknik yang kita miliki untuk mendapatkan kode yang benar, karena Turing datang dengan ide bertahun-tahun yang lalu.
Komentar (21)

Seperti yang lain menyatakan, hal ini tidak diperlukan untuk C, tapi untuk C++. Jika anda berpikir anda akan mengkompilasi kode C dengan C++ compiler, untuk alasan yang pernah, anda dapat menggunakan makro sebaliknya, seperti:

#ifdef __cplusplus
# define NEW(type, count) ((type *)calloc(count, sizeof(type)))
#else
# define NEW(type, count) (calloc(count, sizeof(type)))
#endif

Dengan cara itu anda masih bisa menulis hal itu dalam cara yang sangat kompak:

int *sieve = NEW(int, 1);

dan itu akan mengkompilasi untuk C dan C++.

Komentar (15)

Dari Wikipedia:

Keuntungan untuk pengecoran

  • Termasuk pemain dapat memungkinkan C program atau fungsi untuk mengkompilasi C++.
  • cast memungkinkan untuk pra-1989 versi malloc yang awalnya kembali char *.
  • Casting dapat membantu pengembang mengidentifikasi inkonsistensi dalam jenis sizing harus tujuan pointer jenis perubahan, terutama jika pointer dideklarasikan jauh dari malloc() call (meskipun modern compiler dan statis analisis dapat memperingatkan pada perilaku tersebut tanpa memerlukan cast).

Kerugian untuk pengecoran

  • di Bawah standar ANSI C, cor adalah berlebihan.
  • Menambahkan pemain dapat menutupi kegagalan untuk menyertakan header stdlib.h, di yang prototipe untuk malloc ditemukan. Dalam ketiadaan prototipe untuk malloc, standar mengharuskan C compiler asumsikan malloc kembali int. Jika tidak ada cor, peringatan dikeluarkan saat ini integer ditugaskan untuk pointer; namun, dengan cor, peringatan ini tidak diproduksi, menyembunyikan bug. Pada tertentu arsitektur dan model data (seperti LP64 pada sistem 64-bit, di mana panjang dan pointer 64-bit dan int 32-bit), kesalahan ini dapat benar-benar menghasilkan perilaku tidak terdefinisi, karena secara implisit menyatakan malloc mengembalikan sebuah nilai 32-bit sedangkan yang benar-benar didefinisikan fungsi mengembalikan 64-bit nilai. Tergantung pada konvensi pemanggilan dan memori tata letak, hal ini dapat mengakibatkan tumpukan menghancurkan. Masalah ini kurang mungkin untuk pergi tanpa diketahui di modern compiler, karena mereka memproduksi seragam peringatan yang dideklarasikan fungsi yang telah digunakan, sehingga peringatan akan masih muncul. Misalnya, GCC's perilaku default adalah untuk menunjukkan peringatan yang berbunyi "tidak kompatibel deklarasi implisit built-in fungsi" terlepas dari apakah pemain hadir atau tidak.
  • Jika jenis pointer berubah pada deklarasi, satu mei juga, perlu untuk mengubah semua garis di mana malloc disebut dan cor.

Meskipun malloc tanpa casting adalah metode yang disukai dan paling berpengalaman programmer memilih, anda harus menggunakan apapun yang anda suka setelah menyadari masalah.

aku.e: Jika anda perlu untuk mengkompilasi program C karena C++ (Meskipun itu adalah bahasa yang terpisah) anda harus membuang hasil dari penggunaan malloc.

Komentar (4)

Di C, anda dapat secara implisit mengubah void pointer ke jenis lain dari pointer, sehingga pemain tidak perlu. Menggunakan satu mungkin menyarankan untuk orang awam, bahwa ada beberapa alasan mengapa diperlukan, yang dapat menyesatkan.

Komentar (0)

Anda don't cast hasil malloc, karena hal itu menambah sia-sia kekacauan untuk kode anda.

Alasan yang paling umum mengapa orang-orang cast hasil malloc adalah karena mereka tidak yakin tentang bagaimana bahasa C bekerja. Yang's tanda peringatan: jika anda don't tahu bagaimana bahasa tertentu mekanisme kerjanya, maka don't mengambil menebak. Melihat itu atau meminta pada Stack Overflow.

Beberapa komentar:

  • Void pointer dapat dikonversi ke/dari setiap pointer lain jenis tanpa pemain eksplisit (C11 6.3.2.3 dan 6.5.16.1).

  • C++ namun tidak memungkinkan implisit cor antara void* dan lain penunjuk jenis. Jadi dalam C++, para pemain akan menjadi benar. Tetapi jika anda dalam program C++, anda harus menggunakan baru dan tidak malloc(). Dan anda harus mengkompilasi kode C dengan menggunakan compiler C++.

Jika anda perlu dukungan baik C dan C++ dengan kode sumber yang sama, menggunakan compiler switch untuk menandai perbedaan. Jangan mencoba untuk sate bahasa standar dengan kode yang sama, karena mereka tidak kompatibel.

  • Jika C compiler tidak menemukan fungsi karena anda lupa untuk menyertakan header, anda akan mendapatkan sebuah compiler/linker kesalahan tentang itu. Jadi jika anda lupa untuk menyertakan <stdlib.h> yang's tidak ada masalah besar, anda tidak't dapat membangun program anda.

  • Pada kuno compiler yang mengikuti versi standar yang lebih dari 25 tahun, lupa untuk menyertakan <stdlib.h> akan menghasilkan perilaku yang berbahaya. Karena itu kuno standar, fungsi tanpa terlihat prototipe secara implisit dikonversi jenis kembali ke int. Casting hasil dari malloc secara eksplisit kemudian akan menyembunyikan diri bug ini.

Tapi yang ini benar-benar non-isu. Anda tidak't menggunakan 25 tahun komputer, jadi mengapa anda akan menggunakan 25 tahun compiler?

Komentar (3)

Dalam C anda mendapatkan konversi implisit dari void* lainnya (data) pointer.

Komentar (2)

Casting nilai yang dikembalikan oleh malloc() adalah tidak perlu sekarang, tapi aku'd ingin menambahkan satu titik yang tampaknya tidak ada yang telah menunjukkan:

Pada hari-hari kuno, yaitu, sebelum ANSI C menyediakan void * generik jenis pointer, char * adalah tipe untuk penggunaan tersebut. Dalam hal ini, pemain dapat mematikan peringatan compiler.

Referensi: C FAQ

Komentar (3)

Hal ini tidak wajib untuk cor hasil malloc, karena itu kembali void* , dan void* dapat menunjuk ke tipe data.

Komentar (0)

Hanya menambahkan pengalaman saya, belajar komputer teknik saya melihat bahwa dua atau tiga guru besar yang saya telah melihat tulisan di C selalu cor malloc, namun salah satu yang saya tanya (dengan besar CV dan pemahaman C) mengatakan kepada saya bahwa itu adalah benar-benar tidak perlu, tetapi hanya digunakan untuk menjadi benar-benar spesifik, dan untuk mendapatkan siswa menjadi mentalitas yang benar-benar spesifik. Pada dasarnya, pengecoran tidak akan mengubah apa pun dalam cara kerjanya, itu tidak persis apa yang dikatakannya, mengalokasikan memori, dan pengecoran tidak efek ini, anda mendapatkan memori yang sama, dan bahkan jika anda melemparkan itu ke sesuatu yang lain dengan kesalahan (dan entah bagaimana menghindari kesalahan compiler) C akan mengaksesnya dengan cara yang sama.

Edit: Casting memiliki titik tertentu. Ketika anda menggunakan notasi array, kode yang dihasilkan harus tahu berapa banyak memori tempat-tempat itu untuk maju untuk mencapai awal dari elemen berikutnya, hal ini dicapai melalui casting. Dengan cara ini anda tahu bahwa untuk double kau pergi 8 byte ke depan sementara untuk int kau pergi 4, dan seterusnya. Dengan demikian tidak memiliki efek jika anda menggunakan notasi pointer, dalam notasi array menjadi perlu.

Komentar (3)

Ini adalah apa yang GNU C Library Referensi mengatakan:

Anda dapat menyimpan hasil dari malloc ke dalam variabel pointer tanpa cor, karena ISO C secara otomatis mengubah tipe void * ke yang lain jenis pointer bila diperlukan. Tapi pemain diperlukan dalam konteks lainnya dari penugasan operator atau jika mungkin anda ingin kode anda untuk menjalankan tradisional C.

Dan memang ISO C11 standar (p347) mengatakan demikian:

pointer kembali jika alokasi berhasil sesuai selaras sehingga yang mungkin akan ditugaskan untuk pointer untuk setiap jenis objek dengan mendasar keselarasan kebutuhan dan kemudian digunakan untuk mengakses seperti objek atau sebuah array dari benda-benda tersebut di ruang yang dialokasikan (sampai ruang secara eksplisit deallocated)

Komentar (0)

Void pointer adalah sebuah objek generik pointer dan C mendukung konversi implisit dari kekosongan tipe pointer untuk tipe lainnya, sehingga tidak perlu secara eksplisit typecasting itu.

Namun, jika anda ingin kode yang sama bekerja dengan sempurna kompatibel pada C++, platform, yang tidak mendukung konversi implisit, yang perlu anda lakukan typecasting, jadi itu semua tergantung pada kegunaan.

Komentar (3)

Kembali tipe void*, yang dapat dilemparkan ke jenis yang diinginkan dari data pointer agar dapat dereferenceable.

Komentar (1)

Dalam bahasa C, sebuah void pointer dapat ditugaskan untuk setiap pointer, yang mengapa anda tidak harus menggunakan jenis cast. Jika anda ingin "type yang aman" alokasi, saya dapat merekomendasikan berikut fungsi makro, yang selalu saya gunakan dalam proyek C:

#include 
#define NEW_ARRAY(ptr, n) (ptr) = malloc((n) * sizeof *(ptr))
#define NEW(ptr) NEW_ARRAY((ptr), 1)

Dengan ini di tempat anda hanya bisa mengatakan

NEW_ARRAY(sieve, length);

Untuk non-array dinamis, yang ketiga harus-memiliki fungsi makro adalah

#define LEN(arr) (sizeof (arr) / sizeof (arr)[0])

yang membuat array loop lebih aman dan lebih nyaman:

int i, a[100];

for (i = 0; i < LEN(a); i++) {
   ...
}
Komentar (3)

Hal ini tergantung pada bahasa pemrograman dan compiler. Jika anda menggunakan malloc di C tidak ada kebutuhan untuk tipe cast itu, karena akan secara otomatis tipe cast, Namun jika anda menggunakan C++ maka anda harus jenis cast karena malloc akan kembali void* jenis.

Komentar (1)

Orang-orang digunakan untuk GCC dan Dentang yang manja. It's tidak semua yang baik di luar sana.

Saya telah cukup ngeri selama bertahun-tahun oleh bertumbuhnya usia penyusun I've been diperlukan untuk menggunakan. Seringkali perusahaan dan manajer mengadopsi ultra-konservatif pendekatan untuk mengubah compiler dan bahkan tidak akan tes jika compiler baru ( dengan baik sesuai standar dan kode optimization ) akan bekerja dalam sistem mereka. Dalam kenyataan praktis untuk bekerja pengembang adalah bahwa ketika anda're coding yang anda butuhkan untuk menutupi basis anda dan, sayangnya, casting mallocs adalah kebiasaan yang baik jika anda tidak dapat mengontrol apa yang penyusun dapat diterapkan untuk kode anda.

Saya juga akan menunjukkan bahwa banyak organisasi menerapkan standar pengkodean mereka sendiri dan bahwa yang harus dengan metode orang-orang yang mengikuti jika didefinisikan. Dengan tidak adanya eksplisit bimbingan saya cenderung untuk pergi untuk yang paling mungkin untuk mengkompilasi di mana-mana, bukan budak kepatuhan terhadap standar.

Argumen bahwa itu's tidak diperlukan di bawah standar saat ini cukup valid. Tetapi argumen yang menghilangkan praktik dunia nyata. Kami tidak kode dalam dunia yang dikuasai secara eksklusif oleh standar hari, tapi dengan kepraktisan apa yang saya suka menyebutnya "manajemen lokal's kenyataan lapangan". Dan yang's membungkuk dan memutar lebih dari ruang waktu yang pernah ada. :-)

YMMV.

Saya cenderung berpikir casting malloc sebagai defensif operasi. Tidak cukup, tidak sempurna, tetapi umumnya aman. ( Jujur saja, jika anda've tidak termasuk stdlib.jam maka anda've cara lebih banyak masalah daripada casting malloc ! ).

Komentar (0)

Tidak, anda don't cast hasil dari malloc().

Secara umum, anda *don't cast ke atau dari `void `**.

Khas diberikan alasan untuk tidak melakukannya adalah bahwa kegagalan untuk #include <stdlib.h> bisa pergi tanpa diketahui. Ini isn't masalah lagi untuk waktu yang lama sekarang sebagai C99 dibuat deklarasi fungsi implisit kegiatan ilegal, jadi jika anda compiler yang sesuai untuk setidaknya C99, anda akan mendapatkan pesan diagnostik.

Tapi ada's a banyak alasan kuat tidak untuk memperkenalkan tidak perlu pointer gips:

Dalam C, pointer cor hampir selalu error. Hal ini karena aturan berikut (§6.5 p7 di N1570, draft terbaru untuk C11):

Sebuah objek akan memiliki nilai yang disimpan dan diakses hanya dengan sebuah lvalue ekspresi yang memiliki salah satu jenis berikut: — jenis kompatibel dengan efektif jenis objek, — memenuhi syarat versi dari jenis yang kompatibel dengan efektif jenis objek, — jenis yang ditandatangani atau unsigned jenis yang sesuai dengan jenis efektif dari objek, — jenis yang ditandatangani atau unsigned jenis yang sesuai dengan syarat versi efektif jenis objek, — agregat atau uni jenis yang termasuk salah satu dari jenis tersebut antara anggota (termasuk rekursif, anggota subaggregate atau terkandung union), atau — tipe karakter.

Hal ini juga dikenal sebagai ketat aliasing aturan. Jadi kode berikut ini undefined perilaku:

long x = 5;
double *p = (double *)&x;
double y = *p;

Dan, kadang-kadang mengejutkan, berikut ini juga:

struct foo { int x; };
struct bar { int x; int y; };
struct bar b = { 1, 2};
struct foo *p = (struct foo *)&b;
int z = p->x;

Kadang-kadang, anda do perlu untuk cor pointer, tetapi mengingat ketat aliasing aturan, anda harus sangat berhati-hati dengan itu. Jadi, setiap kejadian dari suatu pointer cor dalam kode anda adalah tempat anda harus periksa untuk keabsahannya. Oleh karena itu, anda tidak pernah menulis tidak perlu pointer cor.

tl;dr

Singkatnya: Karena di C, semua terjadinya pointer cor harus menaikkan bendera merah untuk kode yang memerlukan perhatian khusus, anda harus tidak pernah menulis tidak perlu pointer gips.


Side catatan:

  • Ada kasus di mana anda benar-benar butuhkan * cor untuk `void `, misalnya jika anda ingin mencetak sebuah pointer:

int x = 5; printf("%p\n", (void *)&x);

Pemain diperlukan di sini, karena printf() adalah variadic fungsi, sehingga konversi implisit don't bekerja.

  • Dalam C++, situasinya berbeda. Casting pointer jenis ini agak umum (dan benar) ketika berhadapan dengan objek dari kelas turunan. Oleh karena itu, masuk akal bahwa dalam C++, konversi ke dan dari void * ini tidak implisit. C++ memiliki seluruh rangkaian rasa yang berbeda dari casting.
Komentar (6)

Aku dimasukkan ke dalam cast hanya untuk menunjukkan ketidaksetujuan dari lubang jelek dalam jenis sistem, yang memungkinkan kode seperti cuplikan berikut untuk mengkompilasi tanpa diagnostik, meskipun tidak ada gips yang digunakan untuk membawa tentang konversi buruk:

double d;
void *p = &d;
int *q = p;

Saya berharap bahwa tidak't ada (dan itu doesn't dalam C++) dan jadi saya cor. Itu merupakan selera saya, dan saya pemrograman politik. I'm tidak hanya casting pointer, tapi efektif, casting pemungutan suara, dan mengusir setan-setan dari kebodohan. Jika aku bisa't benar-benar mengusir kebodohan, maka setidaknya biarkan aku mengungkapkan keinginan untuk melakukannya dengan gerakan protes.

Pada kenyataannya, sebuah praktek yang baik adalah untuk membungkus malloc (dan teman-teman) dengan fungsi yang kembali unsigned char *, dan pada dasarnya tidak pernah menggunakan void * dalam kode anda. Jika anda membutuhkan generic pointer-ke-semua-objek, menggunakan char * atau unsigned char *, dan gips di kedua arah. Salah satu relaksasi yang dapat memanjakan, mungkin, adalah menggunakan fungsi-fungsi seperti memset dan memcpy tanpa gips.

Pada topik casting dan C++ kompatibilitas, jika anda menulis kode anda sehingga mengkompilasi sebagai investasi C dan C++ (dalam hal ini anda harus cast yang mengembalikan nilai malloc ketika menetapkan hal ini untuk sesuatu yang lain dari void *), anda bisa melakukan hal yang sangat membantu untuk diri anda sendiri: anda dapat menggunakan makro untuk pengecoran yang menerjemahkan ke C++ style gips ketika menyusun seperti C++, tetapi mengurangi C cor ketika menyusun seperti C:

/* In a header somewhere */
#ifdef __cplusplus
#define strip_qual(TYPE, EXPR) (const_cast(EXPR))
#define convert(TYPE, EXPR) (static_cast(EXPR))
#define coerce(TYPE, EXPR) (reinterpret_cast(EXPR))
#else
#define strip_qual(TYPE, EXPR) ((TYPE) (EXPR))
#define convert(TYPE, EXPR) ((TYPE) (EXPR))
#define coerce(TYPE, EXPR) ((TYPE) (EXPR))
#endif

Jika anda mematuhi makro tersebut, maka sederhana grep pencarian anda untuk kode dasar untuk pengidentifikasi ini akan menunjukkan anda di mana anda gips, sehingga anda dapat memeriksa apakah ada dari mereka yang salah.

Kemudian, ke depan, jika anda secara teratur mengkompilasi kode C++, itu akan memberlakukan penggunaan yang tepat cast. Misalnya, jika anda menggunakan strip_qual hanya untuk menghilangkan const atau volatile, tetapi program perubahan sedemikian rupa sehingga jenis konversi kini terlibat, anda akan mendapatkan diagnostik, dan anda akan memiliki untuk menggunakan kombinasi dari gips untuk mendapatkan konversi yang diinginkan.

Untuk membantu anda mematuhi makro ini, the GNU C++ (tidak C!) compiler memiliki fitur yang indah: opsional diagnostik yang dihasilkan untuk semua kejadian C gaya gips.

-Wold-gaya-cast (C++ dan Objective-C++ only)
Memperingatkan jika lama-gaya (gaya C) cor untuk non-void jenis ini digunakan
dalam program C++. Baru-gaya gips (dynamic_cast,
static_cast, reinterpret_cast, dan const_cast) kurang rentan
untuk efek yang tidak diinginkan dan jauh lebih mudah untuk mencari.

Jika anda mengkompilasi kode C seperti C++, anda dapat menggunakan ini -Wold-gaya-cor pilihan untuk mengetahui semua kejadian (jenis) casting sintaks yang dapat merayap ke dalam kode, dan tindak lanjut pada diagnosa ini dengan menggantinya dengan pilihan yang tepat dari kalangan atas macro (atau kombinasi, jika diperlukan).

Pengobatan ini konversi tunggal terbesar mandiri teknis pembenaran untuk bekerja di sebuah "Bersih C": gabungan C dan C++ dialek, yang pada gilirannya secara teknis membenarkan casting nilai kembali dari malloc.

Komentar (3)

Saya lebih memilih untuk melakukan cast, tapi tidak secara manual. Favorit saya adalah menggunakan g_new dan g_new0 macro dari glib. Jika glib tidak digunakan, saya akan menambahkan yang sama macro. Mereka makro mengurangi duplikasi kode tanpa mengorbankan safety tipe. Jika anda mendapatkan jenis yang salah, anda akan mendapatkan implisit cor antara non-void pointer, yang akan menyebabkan peringatan (error dalam C++). Jika anda lupa untuk menyertakan header yang mendefinisikan g_new dan g_new0, anda akan mendapatkan error. g_new dan g_new0 kedua mengambil argumen yang sama, tidak seperti malloc yang mengambil lebih sedikit argumen dari calloc. Cukup tambahkan 0 untuk mendapatkan nol-diinisialisasi memori. Kode dapat di-compile dengan compiler C++ yang tanpa perubahan.

Komentar (0)