C ++ veya C'de foo (void) ve foo () arasında bir fark var mı?


253

Bu iki işlev tanımını göz önünde bulundurun:

void foo() { }

void foo(void) { }

Bu ikisi arasında herhangi bir fark var mı? Değilse, neden voidargüman orada? Estetik nedenler?


C için Q / A burada
Antti Haapala

Yanıtlar:


317

İçinde C :

  • void foo()" foobelirtilmemiş türde belirtilmemiş sayıda argüman alan bir işlev "
  • void foo(void)" foobağımsız değişken almayan bir işlev" anlamına gelir

Gelen C ++ :

  • void foo()" foobağımsız değişken almayan bir işlev" anlamına gelir
  • void foo(void)" foobağımsız değişken almayan bir işlev" anlamına gelir

Bu foo(void)nedenle, yazarak , her iki dilde de aynı yorumu yapıyoruz ve başlıklarımızı çok dilli yapıyoruz (ancak başlıklara gerçekten çapraz dil yapmak için genellikle biraz daha fazla şey yapmamız gerekiyor; yani, extern "C"derliyorsak C ++).


10
Ancak C ++ gerekli olsaydı void, o zaman "en sinir bozucu ayrıştırma" sorunu önlenmiş olabilir.
Adrian McCarthy

5
Doğru, ama C ++ 'da çok fazla crappy ayrıştırma var, bunlardan herhangi biri hakkında kvetching yapmanın gerçek bir anlamı yok.
DrPizza

16
Son bir soru üzerine, @James Kanze ilginç bir tidbit yayınladı. Kaybetmemek için burada tekrar yayınlayın: C'nin ilk sürümleri bir işlevin alabileceği parametre sayısını belirtmeye izin vermedi, bu nedenle void foo()bir işlevi bildiren tek sözdizimiydi. İmzalar sunulduğunda, C komitesi no parametresini eski sözdiziminden ayırmak zorunda kaldı ve void foo(void)sözdizimini tanıttı . C ++ uyumluluk uğruna aldı.
Matthieu M.

3
Bana C C90 ve daha sonra void foo()bunun yerine kullanmanın void foo(void)fonksiyonel bir fark yaratacağı bir örnek verebilir misiniz ? Yani ben yıllardır geçersiz bir sürüm kullanıyorum ve herhangi bir sorun görmedim, bir şey eksik mi?
chacham15

6
@ chacham15 void foo() { if ( rand() ) foo(5); } derler ve çalışır (çok şanslı değilseniz tanımsız davranışlara neden olur), oysa void foo(void)aynı gövdeye sahip bir derleme hatasına neden olur.
MM

39

Sorunuzun C ++ ile ilgili olduğunu anlıyorum, ancak C söz konusu olduğunda cevap K&R, sayfa 72-73'te bulunabilir:

Ayrıca, bir işlev bildirimi aşağıdaki gibi bağımsız değişkenler içermiyorsa

double atof();

bu da atof'un argümanları hakkında hiçbir şey varsayılmayacağı anlamına gelir; tüm parametre kontrolleri kapalıdır. Boş argüman listesinin bu özel anlamı, eski C programlarının yeni derleyicilerle derlenmesine izin vermeyi amaçlamaktadır. Ancak yeni programlarla kullanmak kötü bir fikirdir. İşlev bağımsız değişkenler alıyorsa, bildiriniz; argüman almazsa, void kullanın.


Ancak soru tanımlarla ilgilidir, bu durumda ilgili C kuralı, bir işlev bildirimindeki bu işlevin tanımının bir parçası olan boş bir listedir, işlevin hiçbir parametresi olmadığını belirtir.
jinawee

9

C ++ 11 N3337 standart taslak

Fark yok.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf

Ek C "Uyumluluk" C.1.7 Madde 8: Beyanlar şöyle demektedir:

8.3.5 Değişiklik: C ++ 'da, boş parametre listesiyle bildirilen bir işlev bağımsız değişken almaz. C'de boş bir parametre listesi, işlev bağımsız değişkenlerinin sayısı ve türünün bilinmediği anlamına gelir.

Misal:

int f();
// means int f(void) in C ++
// int f( unknown ) in C

Gerekçe: Bu, hatalı işlev çağrılarından (yani yanlış sayıda veya türde bağımsız değişkenli işlev çağrılarından) kaçınmak içindir.

Orijinal özellik üzerindeki etki: İyi tanımlanmış özelliğin anlambilimine geçin. Bu özellik C'de “eskimiş” olarak işaretlendi.

8.5.3 fonksiyonları :

4. Parametre-bildirim-deyimi, işlev çağrıldığında belirtilebilen bağımsız değişkenleri ve bunların işlenmesini belirler. [...] Parametre-bildirim-deyimi boşsa, işlev bağımsız değişken almaz. Parametre listesi (void) boş parametre listesine eşdeğerdir.

C99

C ++ 11 tarafından int f()belirtildiği gibi, argümanlar hakkında hiçbir şey belirtmez ve eskimiştir.

Çalışma koduna veya UB'ye yol açabilir.

C99 standardını şu adreste ayrıntılı olarak yorumladım: https://stackoverflow.com/a/36292431/895245


2

C'de, boş bir işlev başvurusunda bir boşluk kullanırsınız, böylece derleyicinin bir prototipi olur ve bu prototipin "bağımsız değişken" olmaz. C ++ 'da, derleyiciye bir prototipiniz olduğunu söylemek zorunda değilsiniz çünkü prototipi dışarıda bırakamazsınız.


1
"prototip", argüman listesi bildirimi ve dönüş türü anlamına gelir. Bunu söylüyorum çünkü “prototip” ilk başta ne demek istediğiniz konusunda beni şaşırttı.
Zan Lynx
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.