int main( const int argc , const char[] const argv)
Karena C ++ Item # 3 yang efektif menyatakan "Gunakan const bila memungkinkan", saya mulai berpikir "mengapa tidak membuat parameter 'konstan' ini const
"?.
Apakah ada skenario di mana nilai dari argc
diubah dalam sebuah program?
argc
sebagaiconst
.--argc
const
; memang, lewatargc
sebagaiconst int
sarana yang tidak bisa Anda gunakanargc
sebagai, katakanlah, penghitung di dalam fungsi.const
parameter pass-by-value. Lihat misalnya stackoverflow.com/a/8714278/277304 dan stackoverflow.com/a/117557/277304Jawaban:
Dalam hal ini, sejarah adalah salah satu faktornya. C mendefinisikan input ini sebagai "tidak konstan", dan kompatibilitas dengan (sebagian besar) kode C yang ada adalah tujuan awal C ++.
Beberapa API UNIX, seperti
getopt
, benar-benar memanipulasiargv[]
, jadi tidak bisa dibuatconst
karena alasan itu juga.(Selain: Menariknya, meskipun
getopt
prototipe menyarankan itu tidak akan memodifikasiargv[]
tetapi dapat memodifikasi string yang ditunjuk, halaman manual Linux menunjukkan bahwagetopt
memperbolehkan argumennya, dan tampaknya mereka tahu mereka nakal . Halaman manual di Open Grup tidak menyebutkan permutasi ini.)Menempatkan
const
padaargc
danargv
tidak akan membeli banyak, dan itu akan membatalkan beberapa tua-sekolah praktek, seperti pemrograman:Saya telah menulis program seperti itu dalam C, dan saya tahu saya tidak sendiri. Saya menyalin contoh dari suatu tempat .
sumber
const
keargv
, tanpa memengaruhi fungsi C apa pun yang dapat dilakukan. Juga,getopt
dideklarasikan sebagaiint getopt(int argc, char * const argv[], const char *optstring);
. Dan di siniconst
bukan tingkat atas, tetapi menyatakan petunjuknyaconst
, janji untuk tidak memodifikasinya (meskipun string yang mereka tunjuk mungkin dapat dimodifikasi).char* const* ___argv
ada di sana, tetapi antarmuka benar-benar melekatconst char **
. Kebingungan seperti itu. Saya telah bingung dengan presedensi[]
dan*
sehubungan denganconst
. Permintaan maaf saya.getopt()
tahu itu tidak mengikuti standar karena memperhatikanPOSIXLY_CORRECT
variabel lingkungan untuk membuatnya berperilaku dengan benar. Secara khusus, POSIX tidak mengubah argumen, dan tidak mencari opsi setelah argumen non-opsi pertama.Standar C (ISO / IEC 9899: 2011) mengatakan:
Perhatikan poin-poin terakhir. Dikatakan bahwa keduanya
argc
danargv
harus dapat dimodifikasi. Mereka tidak harus dimodifikasi, tetapi dapat dimodifikasi.sumber
QApplication(argc,argv)
konstruktor Qt didefinisikan denganargc
referensi . Itu mengejutkanku.argc
biasanya tidak konstan karena tanda tangan fungsi untukmain()
tanggal sebelumnyaconst
.Karena argc adalah variabel tumpukan, mengubahnya tidak akan memengaruhi apa pun selain pemrosesan baris perintah Anda sendiri.
Anda, tentu saja, bebas untuk menyatakannya
const
jika Anda mau.sumber
Level teratas
const
pada argumen formal bukanlah bagian dari tipe fungsi. Anda dapat menambahkan atau menghapusnya sesuka Anda: ini hanya memengaruhi apa yang dapat Anda lakukan dengan argumen dalam implementasi fungsi.Jadi bagi
argc
Anda dapat menambahkan dengan bebas menambahkan fileconst
.Tetapi bagi
argv
Anda tidak dapat membuat data karakterconst
tanpa mengubah fungsi tanda tangan. Artinya, ini bukan salah satumain
tanda tangan fungsi standar , dan tidak perlu dikenali sebagaimain
fungsi. Jadi, bukan ide yang bagus.Alasan yang baik untuk tidak menggunakan
main
argumen standar dalam program non-mainan adalah karena di Windows mereka tidak dapat mewakili argumen program yang sebenarnya seperti nama file dengan karakter internasional. Itu karena di Windows mereka dengan konvensi yang sangat kuat yang dikodekan sebagai Windows ANSI. Di Windows Anda dapat menerapkan beberapa fasilitas akses argumen yang lebih portabel dalam kaitannya denganGetCommandLine
fungsi API.Menyimpulkan, tidak ada yang mencegah Anda dari menambahkan
const
keargc
, tapi yang paling bergunaconst
-ness padaargv
akan memberi Anda non-standarmain
fungsi, sebagian besar mungkin tidak diakui sebagai demikian. Untungnya (dengan cara yang ironis) ada alasan bagus untuk tidak menggunakanmain
argumen standar untuk kode serius portabel. Sederhananya, untuk praktiknya mereka hanya mendukung ASCII lama, dengan hanya huruf alfabet Inggris.sumber
main
tanda tangan standar berfungsi dengan baik dan Anda bisa menerima argumen Unicode sewenang-wenang.Tanda tangan dari
main
adalah semacam artefak sejarah dariC
. Secara historisC
tidak punyaconst
.Namun, Anda dapat mendeklarasikan parameter Anda
const
karena efek const hanya untuk waktu kompilasi.sumber
const
ditambahkan ke C89 / C90; sebelumnya, itu bukan bagian dari C.Karena
argc
adalah variabel lokal (dan, dalam C ++, bukan referensi atau sesuatu), dan karena tempat khususmain
sarana bahwa kecocokan kompatibilitas mundur memberinya sejumlah besar kelonggaran tanpa alasan kuat untuk memaksa aplikasi membuatnya konstan.ini dan banyak variasi lainnya akan dikompilasi pada berbagai kompiler C dan C ++.
Jadi pada akhirnya ini bukan karena argc bukanlah const, hanya saja argc tidak harus seperti itu, tetapi bisa juga jika Anda menginginkannya.
http://ideone.com/FKldHF , C contoh:
http://ideone.com/m1qc9c , C ++ contoh
sumber
-std=c++11
. Clang juga menerimanya tetapi tidak memberiwarning: only one parameter on 'main' declaration [-Wmain]
, dan MSVC hanya memprotes tentang specifier tipe kembalian yang hilang dan kurangnya referensi ke argc. Sekali lagi, 'shenanigans' dan 'kelonggaran' :)Selain alasan historis, alasan yang baik untuk menyimpan argc dan argv non-
const
adalah karena implementasi compiler tidak tahu apa yang akan Anda lakukan dengan argumen ke main, ia hanya tahu bahwa ia harus memberi Anda argumen tersebut.Saat Anda mendefinisikan fungsi Anda sendiri dan prototipe terkait, Anda tahu parameter mana yang dapat Anda buat
const
dan mana yang akan diubah oleh fungsi Anda.Secara ekstrim, Anda dapat mendeklarasikan bahwa semua parameter untuk semua fungsi harus dideklarasikan
const
, dan kemudian jika Anda memiliki alasan untuk mengubahnya (misalnya menurunkan indeks untuk mencari melalui array), Anda harus membuat non-const
variabel lokal dan salin nilaiconst
argumen ke variabel tersebut. Itu membuat pekerjaan menjadi sibuk dan LOC ekstra tanpa manfaat nyata. Penganalisis statis yang layak akan mengambil jika Anda tidak mengubah nilai argumen, dan menyarankan Anda membuat parameterconst
.sumber