2016-03-14 10 views
60

Dies kompiliert ohne Warnungen.Rückgabe void type in C und C++

Ist das in C und C++ erlaubt oder funktioniert es nur in gcc und clang?

Wenn es legal ist, ist es etwas Neues nach C99?

void f(){ 

} 

void f2(){ 
    return f(); 
} 

aktualisieren

als "Rad Lexus", schlug ich das versucht:

$ gcc -Wall -Wpedantic -c x.c 
x.c: In function ‘f2’: 
x.c:7:9: warning: ISO C forbids ‘return’ with expression, in function returning void [-Wpedantic] 
    return f(); 

$ clang -Wall -Wpedantic -c x.c 
x.c:7:2: warning: void function 'f2' should not return void expression [-Wpedantic] 
     return f(); 
     ^ ~~~~~ 
1 warning generated. 

$ gcc -Wall -Wpedantic -c x.cc 
(no errors) 

$ clang -Wall -Wpedantic -c x.cc 
(no errors) 

aktualisieren

Jemand gefragt, wie dieser Aufbau zu helfen ist. Gut ist mehr oder weniger syntaktischer Zucker. Hier ist ein gutes Beispiel:

void error_report(const char *s){ 
    printf("Error %s\n", s); 
    exit(0); 
} 

void process(){ 
    if (step1() == 0) 
     return error_report("Step 1"); 

    switch(step2()){ 
    case 0: return error_report("Step 2 - No Memory"); 
    case 1: return error_report("Step 2 - Internal Error"); 
    } 

    printf("Processing Done!\n"); 
} 
+9

Gewählt, um wieder zu öffnen; Das vorgeschlagene Duplikat war nur für C++. Dies ist auch markiert mit C. (C und C++ unterscheiden sich beträchtlich in ihrer Verwendung von "void"). – Bathsheba

+14

Sie fragen also nach C oder C++? Wählen Sie eine Sprache. – 2501

+8

Hinweis: mit beiden 'gcc -Wall -Wpedantic -std = c99' und' -std = c11', erhalten Sie eine Warnung: "Warnung: ISO C verbietet 'Rückkehr' mit Ausdruck, in Funktion zurückgeben void [-Wpedantic]" . – usr2564301

Antwort

67

C11, 6.8.6.4 "Die return Anweisung":

A return statement with an expression shall not appear in a function whose return type is void .

Keine, können Sie nicht einen Ausdruck verwenden, auch wenn es von void Typ ist.

Aus dem Vorwort des gleichen Dokuments:

Major changes in the second edition included:

[...]

  • return without expression not permitted in function that returns a value (and vice versa)

So war dies eine Änderung von C89 -> C99 (die zweiten Ausgabe des Sprachstandard) und hat auf diese Weise seitdem.


C++ 14, 6.6.3 "Die return Anweisung":

A return statement with an expression of non-void type can be used only in functions returning a value [...] A return statement with an expression of type void can be used only in functions with a return type of cv void; the expression is evaluated just before the function returns to its caller.

Ja, können Sie einen Ausdruck verwenden wenn es von Hohlraumtyp ist (das ist schon gültig seit C++ 98).

+1

"Eine return-Anweisung mit einem Ausdruck vom Typ void kann nur in Funktionen mit dem Rückgabetyp cv void verwendet werden." Warum sollte jemand solchen Unsinn-Code schreiben wollen? Anstatt nur 'void f2() {f(); } '. Scheint es muss irgendwo eine Begründung dafür geben, obwohl es C++ ist? – Lundin

+7

@Lundin: Vorlagen? Ich nehme an. Sieht so aus, als wäre <= C99 auch erlaubt, und C++ hat wahrscheinlich nur dieses Verhalten kopiert. – DevSolar

+0

Aber vor C99 Ich glaube, es verursacht undefiniertes Verhalten. Dies scheint in C++ nicht der Fall zu sein. Warum sollte jemand dann eine Void-Vorlage verwenden, wenn das überhaupt erlaubt ist? – Lundin

13

Dieser Code in C++ erlaubt, aber nicht erlaubt in C

Von Return statement @ cppreference

In a function returning void, the return statement with expression can be used, if the expression type is void.


OTOH in C11 Spezifikationen Entwurf n1570:

Major cha nges in der zweiten Auflage eingeschlossen:

return without expression not permitted in function that returns a value (and vice versa)

(return mit der Expression nicht in Funktion erlaubt, die ein void liefert)

A return statement with an expression shall not appear in a function whose return type is void. A return statement without an expression shall only appear in a function whose return type is void.

und 6.8.6.4 return (selbst wenn der Ausdruck auswertet zu void)

+0

Es wäre besser, den C++ - Standard und möglicherweise Dokument zu zitieren, seit welcher Version die Konstruktion erlaubt ist. cppreference ist keine sehr zuverlässige Quelle, viele Codebeispiele haben Fehler. – chqrlie

+0

@chqrlie Können Sie mir einen Link zu einer Seite geben, auf der das Codebeispiel wring @ en.cppreference ist? –

+0

@MohitJain: nur ein Beispiel: http://en.cppreference.com/w/c/string/byte/strncat kompiliert mit gcc 4.6: 'main.cpp: 31: 1: Warnung: Kontrolle erreicht Ende der nicht void function [-Wendeart] '. Kein Fehler seit C99, aber schlechter Stil. – chqrlie

3

ISO/IEC 9899: 201x Ausschussentwurf sagt das folgende:

6.8.6.4 The return statement

Constraints

  1. return statement with an expression shall not appear in a function whose return type is void.

    A return statement without an expression shall only appear in a function whose return type is void .

Also, es ist verboten in C.


Sie müssen -pedantic Schalter gcc verwenden, um es über Standard Verletzungen zu beklagen:

test.c: In function ‘f2’: 
test.c:6:12: warning: ISO C forbids ‘return’ with expression, in function returning void 
      [-Wpedantic] 
    return f(); 
1

Standard C nicht unterstützt diese Konstruktion:

C11 6.8.6.4: The return statement

Constraints

1 A return statement with an expression shall not appear in a function whose return type is void . A return statement without an expression shall only appear in a function whose return type is void .

keine besonderen Bestimmungen hinzugefügt werden für den Sonderfall in der Frage. Einige C-Compiler unterstützen dies als Erweiterung (gcc tut dies, wenn sie nicht dazu aufgefordert werden, einer der C-Standards zu entsprechen), aber C11 und frühere Versionen betrachten dies als Constraint-Verletzung.

5

C++ ermöglicht es so etwas wie das:

void f() 
{ 
    return void(); 
} 

Während C nicht. Deshalb wird eine Warnung ausgegeben, wenn Sie ein ISO C anstelle von ISO C++ kompilieren. Dies wird formell beschrieben als:

A return statement with an expression of type void can be used only in functions with a return type of cv void

+0

Es sieht korrekt aus, aber Standard-Referenzen für beide Ansprüche wäre nett. – HolyBlackCat