void foo()oznacza „funkcję foopobierającą nieokreśloną liczbę argumentów nieokreślonego typu”
void foo(void)oznacza „funkcję foobez argumentów”
W C ++ :
void foo()oznacza „funkcję foobez argumentów”
void foo(void)oznacza „funkcję foobez argumentów”
foo(void)Dlatego pisząc , osiągamy taką samą interpretację w obu językach i sprawiamy, że nasze nagłówki są wielojęzyczne (chociaż zwykle musimy zrobić coś więcej z nagłówkami, aby były naprawdę wielojęzyczne; mianowicie, zawijamy je, extern "C"jeśli się kompilujemy C ++).
Ale gdyby C ++ wymagało tego void, to mógłby uniknąć problemu „najbardziej dokuczliwej analizy”.
Adrian McCarthy
5
To prawda, ale w C ++ jest tak wiele innych kiepskich analiz, że nie ma sensu kvetchować o żadnym z nich.
DrPizza
16
W ostatnim pytaniu @James Kanze opublikował ciekawy smakołyk. Prześlij tutaj tutaj, aby go nie zgubić: pierwsze wersje C nie pozwalały na określenie liczby parametrów, które może przyjąć funkcja, dlatego void foo()była to jedyna składnia, która deklarowała funkcję. Kiedy podpisy zostały wprowadzone, komitet C musiał ujednoznacznić parametr no ze starej składni i wprowadził void foo(void)składnię. C ++ wziął to ze względu na kompatybilność.
Matthieu M.,
3
Czy możesz podać mi przykład C C90, a później gdzie użycie void foo()zamiast void foo(void)spowoduje funkcjonalną różnicę? Tj. Używam wersji bez pustki od wielu lat i nie widziałem żadnego problemu, czy coś mi umknęło?
chacham15
6
@ chacham15 void foo() { if ( rand() ) foo(5); } kompiluje się i uruchamia (powoduje niezdefiniowane zachowanie, chyba że masz dużo szczęścia), podczas gdy void foo(void)przy tym samym ciele może wystąpić błąd kompilacji.
MM
39
Zdaję sobie sprawę, że twoje pytanie dotyczy C ++, ale jeśli chodzi o C, odpowiedź można znaleźć w K&R, strony 72-73:
Ponadto, jeśli deklaracja funkcji nie zawiera argumentów, jak w
double atof();
to również oznacza, że nie można nic zakładać o argumentach atof; wszystkie sprawdzanie parametrów jest wyłączone. To specjalne znaczenie pustej listy argumentów ma na celu umożliwienie starszym programom C kompilacji z nowymi kompilatorami. Ale to zły pomysł, aby używać go z nowymi programami. Jeśli funkcja przyjmuje argumenty, zadeklaruj je; jeśli nie przyjmuje żadnych argumentów, użyj void.
Ale pytanie dotyczy definicji, w takim przypadku odpowiednią regułą C jest pusta lista w deklaratorze funkcji, która jest częścią definicji tej funkcji, określa, że funkcja nie ma parametrów.
Załącznik C „Zgodność” C.1.7 Klauzula 8: Deklaratorzy mówią:
8.3.5 Zmiana: W C ++ funkcja zadeklarowana z pustą listą parametrów nie przyjmuje żadnych argumentów. W C pusta lista parametrów oznacza, że liczba i typ argumentów funkcji są nieznane.
Przykład:
int f();// means int f(void) in C ++// int f( unknown ) in C
Uzasadnienie: Ma to na celu uniknięcie błędnych wywołań funkcji (tj. Wywołań funkcji z niewłaściwą liczbą lub rodzajem argumentów).
Wpływ na pierwotny element: przejście na semantykę dobrze zdefiniowanego elementu. Ta funkcja została oznaczona jako „przestarzała” w C.
Funkcje 8.5.3 mówią:
4. Klauzula parametr-deklaracja określa argumenty, które można określić, i ich przetwarzanie, gdy funkcja jest wywoływana. [...] Jeśli klauzula deklaracja parametru jest pusta, funkcja nie przyjmuje argumentów. Lista parametrów (void) jest równoważna pustej liście parametrów.
C99
Jak wspomniano w C ++ 11, int f()nic nie określa argumentów i jest przestarzały.
W C używasz pustki w pustym odwołaniu do funkcji, dzięki czemu kompilator ma prototyp, a ten prototyp nie ma „argumentów”. W C ++ nie musisz informować kompilatora, że masz prototyp, ponieważ nie możesz go pominąć.
Odpowiedzi:
W C :
void foo()
oznacza „funkcjęfoo
pobierającą nieokreśloną liczbę argumentów nieokreślonego typu”void foo(void)
oznacza „funkcjęfoo
bez argumentów”W C ++ :
void foo()
oznacza „funkcjęfoo
bez argumentów”void foo(void)
oznacza „funkcjęfoo
bez argumentów”foo(void)
Dlatego pisząc , osiągamy taką samą interpretację w obu językach i sprawiamy, że nasze nagłówki są wielojęzyczne (chociaż zwykle musimy zrobić coś więcej z nagłówkami, aby były naprawdę wielojęzyczne; mianowicie, zawijamy je,extern "C"
jeśli się kompilujemy C ++).źródło
void
, to mógłby uniknąć problemu „najbardziej dokuczliwej analizy”.void foo()
była to jedyna składnia, która deklarowała funkcję. Kiedy podpisy zostały wprowadzone, komitet C musiał ujednoznacznić parametr no ze starej składni i wprowadziłvoid foo(void)
składnię. C ++ wziął to ze względu na kompatybilność.void foo()
zamiastvoid foo(void)
spowoduje funkcjonalną różnicę? Tj. Używam wersji bez pustki od wielu lat i nie widziałem żadnego problemu, czy coś mi umknęło?void foo() { if ( rand() ) foo(5); }
kompiluje się i uruchamia (powoduje niezdefiniowane zachowanie, chyba że masz dużo szczęścia), podczas gdyvoid foo(void)
przy tym samym ciele może wystąpić błąd kompilacji.Zdaję sobie sprawę, że twoje pytanie dotyczy C ++, ale jeśli chodzi o C, odpowiedź można znaleźć w K&R, strony 72-73:
źródło
Wersja standardowa C ++ 11 N3337
Nie ma różnicy.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf
Załącznik C „Zgodność” C.1.7 Klauzula 8: Deklaratorzy mówią:
Funkcje 8.5.3 mówią:
C99
Jak wspomniano w C ++ 11,
int f()
nic nie określa argumentów i jest przestarzały.Może to prowadzić do działania kodu lub UB.
Szczegółowo zinterpretowałem standard C99 pod adresem : https://stackoverflow.com/a/36292431/895245
źródło
W C używasz pustki w pustym odwołaniu do funkcji, dzięki czemu kompilator ma prototyp, a ten prototyp nie ma „argumentów”. W C ++ nie musisz informować kompilatora, że masz prototyp, ponieważ nie możesz go pominąć.
źródło