Standar C ++ 11 (ISO / IEC 14882: 2011) mengatakan dalam § C.1.1
:
char* p = "abc"; // valid in C, invalid in C++
Untuk C ++ tidak apa-apa sebagai pointer ke String Literal berbahaya karena setiap upaya untuk mengubahnya menyebabkan crash. Tetapi mengapa itu valid dalam C?
C ++ 11 juga mengatakan:
char* p = (char*)"abc"; // OK: cast added
Yang berarti bahwa jika para pemain ditambahkan ke pernyataan pertama itu menjadi valid.
Mengapa casting membuat pernyataan kedua valid dalam C ++ dan bagaimana perbedaannya dari yang pertama? Bukankah itu masih berbahaya? Jika itu masalahnya, mengapa standar mengatakan tidak apa-apa?
char[]
di tempat pertama. Yang kedua adalahconst_cast
penyamaran.OK
.const
, jadi mereka tentu tidakconst
.Jawaban:
Hingga C ++ 03, contoh pertama Anda valid, tetapi menggunakan konversi implisit yang sudah usang - string literal harus diperlakukan sebagai tipe
char const *
, karena Anda tidak dapat mengubah kontennya (tanpa menyebabkan perilaku yang tidak ditentukan).Pada C ++ 11, konversi implisit yang telah ditinggalkan secara resmi dihapus, jadi kode yang bergantung padanya (seperti contoh pertama Anda) tidak boleh lagi dikompilasi.
Anda telah mencatat satu cara untuk memungkinkan kode untuk dikompilasi: meskipun konversi implisit telah dihapus, konversi eksplisit masih berfungsi, sehingga Anda dapat menambahkan gips. Namun, saya tidak akan menganggap ini "memperbaiki" kode.
Benar-benar memperbaiki kode memerlukan mengubah jenis pointer ke tipe yang benar:
Mengenai mengapa itu diizinkan dalam C ++ (dan masih dalam C): hanya karena ada banyak kode yang ada yang bergantung pada konversi implisit itu, dan memecah kode itu (setidaknya tanpa peringatan resmi) tampaknya seperti komite standar seperti ide yang buruk.
sumber
char const *p = "abc";
adalah "sah dan aman di kedua C dan C ++", bukan "sah dan aman di baik C atau C ++".Ini valid dalam C karena alasan historis. C secara tradisional menentukan bahwa jenis string literal
char *
lebih daripadaconst char *
, meskipun memenuhi syarat dengan mengatakan bahwa Anda tidak benar-benar diizinkan untuk memodifikasinya.Saat Anda menggunakan gips, Anda pada dasarnya memberi tahu kompiler bahwa Anda tahu lebih baik dari aturan pencocokan tipe default, dan itu membuat tugas OK.
sumber
char[N]
dan diubah menjadiconst char[N]
. Ini memiliki informasi ukuran yang melekat padanya.char[N]
tetapi tidakchar*
eg"abc"
ischar[4]
Anda juga dapat menggunakan strdup :
sumber