Apakah ada perbedaan antara foo (void) dan foo () dalam C ++ atau C?


253

Pertimbangkan dua definisi fungsi ini:

void foo() { }

void foo(void) { }

Apakah ada perbedaan antara keduanya? Jika tidak, mengapa voidargumennya ada? Alasan estetika?


Karena C, Q / A ada di sini
Antti Haapala

Jawaban:


317

Dalam C :

  • 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 ++).


10
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.
jinawee

9

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.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.

Itu bisa mengarah ke kode kerja atau UB.

Saya telah menafsirkan standar C99 secara terperinci di: https://stackoverflow.com/a/36292431/895245


2

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.


1
"prototipe" berarti deklarasi daftar argumen dan jenis kembali. Saya mengatakan ini karena "prototipe" membingungkan saya tentang apa yang Anda maksudkan pada awalnya.
Zan Lynx
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.