void foo()berarti "suatu fungsi yang foomengambil jumlah argumen yang tidak ditentukan dari jenis yang tidak ditentukan"
void foo(void)berarti "suatu fungsi footanpa argumen"
Dalam C ++ :
void foo()berarti "suatu fungsi footanpa argumen"
void foo(void)berarti "suatu fungsi footanpa argumen"
Oleh foo(void)karena itu, dengan menulis , kami mencapai interpretasi yang sama di kedua bahasa dan membuat tajuk kami multibahasa (meskipun kami biasanya perlu melakukan beberapa hal lebih lanjut ke tajuk untuk membuat mereka benar-benar lintas-bahasa; yaitu, membungkusnya dalam extern "C"jika kami menyusun C ++).
Tetapi jika C ++ memerlukannya void, maka itu bisa menghindari masalah "yang paling menjengkelkan".
Adrian McCarthy
5
Benar, tetapi ada begitu banyak parsing jelek lainnya di C ++ tidak ada gunanya kvetching tentang salah satu dari mereka.
DrPizza
16
Pada pertanyaan terakhir, @James Kanze memposting berita menarik. Repost di sini untuk menghindari kehilangannya: versi pertama C tidak memungkinkan untuk menentukan jumlah parameter fungsi yang mungkin diambil, dengan demikian void foo()adalah satu-satunya sintaks untuk mendeklarasikan suatu fungsi. Ketika tanda tangan diperkenalkan, komite C harus mendisambiguasikan tidak ada parameter dari sintaks lama, dan memperkenalkan void foo(void)sintaksis. C ++ mengambilnya demi kompatibilitas.
Matthieu M.
3
Bisakah Anda memberi saya contoh C C90 dan nanti di mana menggunakan void foo()bukannya void foo(void)akan menghasilkan perbedaan fungsional? Yaitu saya telah menggunakan versi tanpa kekosongan selama bertahun-tahun dan tidak melihat masalah, apakah saya kehilangan sesuatu?
chacham15
6
@ chacham15 void foo() { if ( rand() ) foo(5); } mengkompilasi dan menjalankan (menyebabkan perilaku tidak terdefinisi kecuali Anda sangat beruntung), sedangkan void foo(void)dengan tubuh yang sama akan menyebabkan kesalahan kompilasi.
MM
39
Saya menyadari pertanyaan Anda berkaitan dengan C ++, tetapi ketika sampai pada C jawabannya dapat ditemukan di K&R, halaman 72-73:
Lebih lanjut, jika deklarasi fungsi tidak menyertakan argumen, seperti pada
double atof();
itu juga berarti bahwa tidak ada yang dapat diasumsikan tentang argumen atof; semua pemeriksaan parameter dimatikan. Arti khusus dari daftar argumen kosong ini dimaksudkan untuk mengizinkan program C lama untuk dikompilasi dengan kompiler baru. Tapi itu ide yang buruk untuk menggunakannya dengan program baru. Jika fungsi mengambil argumen, nyatakanlah; jika tidak membutuhkan argumen, gunakan void.
Tetapi pertanyaannya adalah tentang definisi, dalam hal ini aturan C yang relevan adalah Daftar kosong dalam deklarator fungsi yang merupakan bagian dari definisi fungsi yang menentukan bahwa fungsi tidak memiliki parameter.
Lampiran C "Kompatibilitas" C.1.7 Klausa 8: deklarator mengatakan:
8.3.5 Ubah: Di C ++, fungsi yang dideklarasikan dengan daftar parameter kosong tidak membutuhkan argumen. Dalam C, daftar parameter kosong berarti bahwa jumlah dan jenis argumen fungsi tidak diketahui.
Contoh:
int f();// means int f(void) in C ++// int f( unknown ) in C
Dasar Pemikiran: Ini untuk menghindari panggilan fungsi yang salah (mis., Panggilan fungsi dengan nomor atau jenis argumen yang salah).
Efek pada fitur asli: Ubah ke semantik fitur yang terdefinisi dengan baik. Fitur ini ditandai sebagai "usang" dalam C.
8.5.3 fungsi mengatakan:
4. Parameter-deklarasi-klausa menentukan argumen yang dapat ditentukan, dan pemrosesan mereka, ketika fungsi dipanggil. [...] Jika klausa deklarasi-parameter kosong, fungsinya tidak membutuhkan argumen. Daftar parameter (kosong) sama dengan daftar parameter kosong.
C99
Seperti yang disebutkan oleh C ++ 11, int f() tidak menyebutkan apa pun tentang argumen, dan sudah usang.
Di C, Anda menggunakan void dalam referensi fungsi kosong sehingga kompiler memiliki prototipe, dan prototipe itu memiliki "tidak ada argumen". Dalam C ++, Anda tidak perlu memberi tahu kompiler bahwa Anda memiliki prototipe karena Anda tidak dapat meninggalkan prototipe.
"prototipe" berarti deklarasi daftar argumen dan jenis kembali. Saya mengatakan ini karena "prototipe" membingungkan saya tentang apa yang Anda maksudkan pada awalnya.
Jawaban:
Dalam C :
void foo()
berarti "suatu fungsi yangfoo
mengambil jumlah argumen yang tidak ditentukan dari jenis yang tidak ditentukan"void foo(void)
berarti "suatu fungsifoo
tanpa argumen"Dalam C ++ :
void foo()
berarti "suatu fungsifoo
tanpa argumen"void foo(void)
berarti "suatu fungsifoo
tanpa argumen"Oleh
foo(void)
karena itu, dengan menulis , kami mencapai interpretasi yang sama di kedua bahasa dan membuat tajuk kami multibahasa (meskipun kami biasanya perlu melakukan beberapa hal lebih lanjut ke tajuk untuk membuat mereka benar-benar lintas-bahasa; yaitu, membungkusnya dalamextern "C"
jika kami menyusun C ++).sumber
void
, maka itu bisa menghindari masalah "yang paling menjengkelkan".void foo()
adalah satu-satunya sintaks untuk mendeklarasikan suatu fungsi. Ketika tanda tangan diperkenalkan, komite C harus mendisambiguasikan tidak ada parameter dari sintaks lama, dan memperkenalkanvoid foo(void)
sintaksis. C ++ mengambilnya demi kompatibilitas.void foo()
bukannyavoid foo(void)
akan menghasilkan perbedaan fungsional? Yaitu saya telah menggunakan versi tanpa kekosongan selama bertahun-tahun dan tidak melihat masalah, apakah saya kehilangan sesuatu?void foo() { if ( rand() ) foo(5); }
mengkompilasi dan menjalankan (menyebabkan perilaku tidak terdefinisi kecuali Anda sangat beruntung), sedangkanvoid foo(void)
dengan tubuh yang sama akan menyebabkan kesalahan kompilasi.Saya menyadari pertanyaan Anda berkaitan dengan C ++, tetapi ketika sampai pada C jawabannya dapat ditemukan di K&R, halaman 72-73:
sumber
C ++ 11 N3337 konsep standar
Tidak ada perbedaan.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf
Lampiran C "Kompatibilitas" C.1.7 Klausa 8: deklarator mengatakan:
8.5.3 fungsi mengatakan:
C99
Seperti yang disebutkan oleh C ++ 11,
int f()
tidak menyebutkan apa pun tentang argumen, dan sudah usang.Itu bisa mengarah ke kode kerja atau UB.
Saya telah menafsirkan standar C99 secara terperinci di: https://stackoverflow.com/a/36292431/895245
sumber
Di C, Anda menggunakan void dalam referensi fungsi kosong sehingga kompiler memiliki prototipe, dan prototipe itu memiliki "tidak ada argumen". Dalam C ++, Anda tidak perlu memberi tahu kompiler bahwa Anda memiliki prototipe karena Anda tidak dapat meninggalkan prototipe.
sumber