Forum: PC-Programmierung Wann void, wann nicht (in C)


von nuname (Gast)


Lesenswert?

Eine elementare Frage zur C-Programmierung:

wann nimmt man in Funktionsheadern üblicherweise nun eigentlich void und 
wann nicht. Es dürften ja beide Funktionsheader irgendwie richtig sein 
bzw werden beide Varianten von aktuellen Compilern als richtig 
anerkannt:

void print(void) { ... }

print() { ... }

Danke

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

nuname schrieb:
> void print(void) { ... }

Das ist C89 ("ANSI-C") und neuer, sowie C++. Bei Funktionsprototypen 
werden die verwendeten Typen angegeben, so daß der Compiler bei 
Funktionsaufrufen eine Typüberprüfung vornehmen kann.


> print() { ... }

Das ist Steinzeit-C ("K&R-C") oder eine C++-Ausnahme.

In C++ wird da ein implizites void angenommen, in Steinzeit-C gibt es 
keine Typüberprüfung von Funktionsargumenten.

von Peter II (Gast)


Lesenswert?

mit void legt du fest das es kein Parameter geben darf, wenn nur () 
steht dann können kann man beliebige parameter übergeben.

Aber das mehr nur in der forward deklartion sinn, nicht in der 
implementierung

von nuname (Gast)


Lesenswert?

Danke.

Habe ich das nun richtg verstanden:

/* Prototypen */
void print(void);

/* Funktionen */
print(){
...}

Das bedeutet aber dann wiederrum für die Funktionen, für die kein 
Prototyp eingesetzt wird, weil sie dem Compiler vor dem ersten Aufruf 
durch entsprechende Reihenfolge schon bekannt waren, dass dort das void 
im eigentlichen Funktionsheader verwendet werden sollte ?

von Peter II (Gast)


Lesenswert?

nuname schrieb:
> Habe ich das nun richtg verstanden:

nein


Das ist OK:

/* Prototypen */
void print();

/* Funktionen */
print(int ab, int b){...}



Das ist falsch:

/* Prototypen */
void print(void);

/* Funktionen */
print(int ab, int b){...}

von nuname (Gast)


Lesenswert?

Peter II schrieb:
> Das ist OK:
>
> /* Prototypen */
> void print();
>
> /* Funktionen */
> print(int ab, int b){...}

Die Frage war doch in dem  Fall, wie es nun richtig aussehen muss, wenn 
der Funktion keine Parameter übergeben werden.

von Peter II (Gast)


Lesenswert?

nuname schrieb:
> Die Frage war doch in dem  Fall, wie es nun richtig aussehen muss, wenn
> der Funktion keine Parameter übergeben werden.

dann muss es print(void) sein, aber in C++ reicht dafür print();

aber mit  print(void) ist es eindeutig in C und C++

von Rolf Magnus (Gast)


Lesenswert?

Rufus Τ. Firefly schrieb:
> nuname schrieb:
>> void print(void) { ... }
>
> Das ist C89 ("ANSI-C") und neuer, sowie C++. Bei Funktionsprototypen
> werden die verwendeten Typen angegeben, so daß der Compiler bei
> Funktionsaufrufen eine Typüberprüfung vornehmen kann.

Dabei wird als spezielle Ausnahme für "keine Parameter" ein "void" 
reingeschrieben, weil eine leere Liste in der vor-ANSI-Zeit schon eine 
andere Bedeutung bekommen hatte.

>> print() { ... }
>
> Das ist Steinzeit-C ("K&R-C") oder eine C++-Ausnahme.
> In C++ wird da ein implizites void angenommen,

Ich würde es anders formulieren: In C++ wird das angenommen, was da 
steht, nämlich keine Parameter. Dort gibt's also keine Ausnahme, sondern 
vielmehr wurde die K&R-Ausnahme nicht aus C übernommen.

> in Steinzeit-C gibt es keine Typüberprüfung von Funktionsargumenten.

Deshalb war da das () ohne void auch schon dafür belegt und wurde aus 
Kompatibilitätsgründen beibehalten. Bei C++ hat man diesen Zopf 
abgeschnitten, da es sowieso die alte K&R-Variante nicht mehr 
unterstützt. Deshalb ist dort auch ohne die void-"Krücke" die 
Parameterliste leer.

nuname schrieb:
> Die Frage war doch in dem  Fall, wie es nun richtig aussehen muss, wenn
> der Funktion keine Parameter übergeben werden.

Dann muß bei der Deklaration das (void) dranstehen. Wichtig ist, daß der 
Aufrufer weiß, daß die Liste leer ist, also muß die Deklaration, die 
dieser sieht, das (void) haben.

von Arc N. (arc)


Lesenswert?

C99:
T n() { } ist eine Definition für eine Funktion die keine Parameter hat
T n(); dagegen eine Deklaration für eine Funktion die beliebig viele 
Parameter akzeptiert.
wird für T nichts angegeben wird int angenommen
T kann definiert werden ala struct A { int a; } name(struct B { int b; } 
a);

C++:
T n(void); ist äquivalent zu T n();
T muss angegeben werden und muss vorher bekannt sein, ebenso wie die 
Typen der Parameter

von Rolf Magnus (Gast)


Lesenswert?

Arc Net schrieb:
> C++:
> T n(void); ist äquivalent zu T n();
> T muss angegeben werden und muss vorher bekannt sein, ebenso wie die
> Typen der Parameter

Wobei es zum "bekannt sein" auch schon reicht, wenn der Typ nur 
deklariert ist:
1
struct T;
2
T n();

wäre ohne weitere Informationen über T ok. Erst in der Definition der 
Funktion und bei ihrem Aufruf muß T dann komplett definiert sein. Bei 
Templates wird's dann noch etwas komplizierter.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.