Apa perbedaan antara function () dan function (void)?

27

Saya telah mendengar bahwa ini adalah praktik yang baik untuk menulis fungsi yang tidak menerima apa pun sebagai parameter seperti ini:

int func(void);

Tetapi saya mendengar bahwa cara yang tepat untuk mengekspresikannya adalah seperti ini:

int func();

Apa perbedaan antara kedua deklarasi fungsi ini di C dan C ++?

Grizzly
sumber
5
Ini adalah duplikat dari seribu pertanyaan lain di jaringan situs, antara lain stackoverflow.com/questions/18167390/…
Lars Viklund
@ LarsViklund itu hanya duplikat jika ada pertanyaan di situs ini. Saya tidak dapat menemukannya, jadi terlepas dari apa yang ada di SO, ini bukan duplikat. Mungkin layak menyimpan pertanyaan ini sebagai rambu jika tidak ada yang lain.
1
@LightnessRacesinOrbit kami bahas dalam obrolan dan memutuskan untuk tetap melakukannya dengan beberapa suntingan.

Jawaban:

17

C dan C ++ berbeda dalam hal ini.

C 2011 Online Standard

6.7.6.3 Deklarator fungsi (termasuk prototipe)
...
10 Kasus khusus dari parameter tipe yang tidak disebutkan namanya voidsebagai satu-satunya item dalam daftar menentukan bahwa fungsi tidak memiliki parameter.
...
14 Daftar pengidentifikasi hanya menyatakan pengidentifikasi parameter fungsi. Daftar kosong di deklarator fungsi yang merupakan bagian dari definisi fungsi yang menentukan bahwa fungsi tidak memiliki parameter. Daftar kosong dalam deklarator fungsi yang bukan bagian dari definisi fungsi itu menentukan bahwa tidak ada informasi tentang jumlah atau jenis parameter yang disediakan. 145)

Singkatnya, daftar parameter kosong dalam deklarasi fungsi menunjukkan bahwa fungsi tersebut mengambil jumlah parameter yang tidak ditentukan , sedangkan daftar parameter kosong dalam definisi fungsi menunjukkan bahwa fungsi tersebut tidak mengambil parameter.

T foo( void ); // declaration, foo takes no parameters
T bar();       // declaration, bar takes an *unspecified* number of parameters

T foo( void ) { ... } // definition, foo takes no parameters
T bar() { ... }       // definition, bar takes no parameters

Sejauh menyangkut C, Anda tidak boleh menggunakan daftar pengidentifikasi kosong dalam deklarasi atau definisi fungsi . Jika suatu fungsi tidak dimaksudkan untuk mengambil parameter apa pun, tentukan dengan menggunakan voiddalam daftar parameter.

Online C ++ standar

8.3.5 Fungsi [dcl.fct]
...
4 Parameter-declaration-clause menentukan argumen yang dapat ditentukan, dan pemrosesan mereka, ketika fungsi dipanggil. [ Catatan: yang parameter-deklarasi-klausul digunakan untuk mengkonversi argumen ditentukan pada panggilan fungsi; lihat 5.2.2. - end note ] Jika parameter-declaration-klausa kosong, fungsinya tidak membutuhkan argumen. Daftar parameter yang terdiri dari parameter tunggal tanpa nama dari tipe yang tidak bergantung voidsama dengan daftar parameter kosong. Kecuali untuk kasus khusus ini, suatu parameter tidak boleh memiliki tipe cv void. Jika parameter-deklarasi-klausadiakhiri dengan ellipsis atau paket parameter fungsi (14.5.3), jumlah argumen harus sama dengan atau lebih besar dari jumlah parameter yang tidak memiliki argumen default dan bukan paket parameter fungsi. Di mana secara sintaksis benar dan di mana "..." bukan bagian dari deklarator abstrak , ", ..." identik dengan "...". [ Contoh: deklarasi
    int printf(const char*, ...);
mendeklarasikan fungsi yang dapat dipanggil dengan jumlah dan tipe argumen yang berbeda-beda.
    printf("hello world");
    printf("a=%d b=%d", a, b);
Namun, argumen pertama harus dari jenis yang dapat dikonversi ke const char*- akhir contoh ] [ Catatan: Header standar <cstdarg>berisi mekanisme untuk argumen mengakses lulus menggunakan elipsis (lihat 5.2.2 dan 18,10). - catatan akhir ]

Dalam kasus C ++, daftar parameter kosong baik dalam deklarasi atau definisi menunjukkan bahwa fungsi tidak mengambil argumen, dan setara dengan menggunakan daftar parameter void.

John Bode
sumber
35

Dalam C, fungsi dengan daftar parameter kosong ()dapat mengambil apa saja untuk argumennya. Apa pun secara harfiah. Ini biasanya digunakan untuk mengimplementasikan suatu fungsi yang dapat mengambil sejumlah variabel argumen , meskipun hari ini dianggap lebih baik menggunakan sintaksis ellipsis yang lebih eksplisit (...)untuk fungsi-fungsi ini.

Dalam C, fungsi dengan daftar parameter (void)secara eksplisit tidak membutuhkan argumen apa pun . Itu berarti kompiler benar-benar dapat memberi tahu Anda bahwa Anda telah membuat kesalahan jika Anda mencoba untuk melewatkan sesuatu.

Dalam C ++, deklarasi fungsi ini setara. Daftar parameter kosong berarti "tidak ada parameter" sama dengan yang voidada.

Ixrec
sumber
Re: "Ini biasanya digunakan untuk mengimplementasikan suatu fungsi yang dapat mengambil sejumlah variabel argumen": Apakah Anda yakin tentang ini? Saya tidak berpikir saya pernah melihat sebuah program yang menggunakan daftar parameter eksplisit untuk deklarasi maju dari fungsi non-variadik dan ()untuk mereka yang variadic. Apakah Anda memiliki contoh program yang menggunakan konvensi ini?
ruakh
4
Fungsi AC variadic harus didefinisikan dengan ...sintaks, dan harus memiliki setidaknya satu parameter bernama. Mendefinisikan fungsi seperti itu dengan ()menyebabkan perilaku tidak terdefinisi - dan tidak ada cara bagi tubuh fungsi untuk menggunakan makro yang didefinisikan <stdarg.h>untuk membaca nilai parameter. Ini telah terjadi sejak standar 1989/1990.
Keith Thompson
@KeithThompson: Pertanyaan ini, dan jawaban ini, berbicara tentang pra-pengumuman, bukan definisi fungsi.
ruakh
3
@ruakh: Fungsi variadic harus dideklarasikan dan didefinisikan menggunakan ...sintaks untuk menghindari perilaku yang tidak terdefinisi.
Keith Thompson