Geben Sie den void-Typ in C und C++ zurück

Lesezeit: 3 Minuten

Benutzeravatar von Nick
Nick

Dies wird ohne Warnungen kompiliert.

Ist das in C und C++ legal 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

wie “Rad Lexus” vorgeschlagen hat, habe ich Folgendes 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 fragte, wie diese Konstruktion hilft. 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");
}

  • Für die Wiedereröffnung gestimmt; Das vorgeschlagene Duplikat war nur für C++. Dies ist auch mit C gekennzeichnet. (C und C++ unterscheiden sich erheblich in der Verwendung von void).

    – Bathseba

    14. März 2016 um 12:34 Uhr


  • Sie fragen also nach C oder C++? Wählen Sie eine Sprache aus.

    – 2501

    14. März 2016 um 12:37 Uhr


  • Hinweis: mit beiden gcc -Wall -Wpedantic -std=c99 und -std=c11erhalten Sie eine Warnung: “Warnung: ISO C verbietet ‘Rückgabe’ mit Ausdruck, in Funktion, die void zurückgibt [-Wpedantic]”.

    – Jongware

    14. März 2016 um 12:39 Uhr

  • @HolyBlackCat: Kann ich auch gleichzeitig nach C, C++ und Java fragen? 😉

    – DevSolar

    14. März 2016 um 12:40 Uhr

  • @DevSolar: D Nun, ich werde das klarer sagen. IMO ist es legitim, nach einer Funktion zu fragen, die sowohl in C als auch in C++ vorhanden ist. Normalerweise verhalten sich diese Features in beiden Sprachen ähnlich. Wenn nicht, würde eine gute Antwort den Unterschied beschreiben.

    – HolyBlackCat

    14. März 2016 um 12:43 Uhr

Benutzeravatar von DevSolar
DevSolar

C116.8.6.4 „Die return Aussage”:

EIN return Anweisung mit einem Ausdruck darf nicht in einer Funktion erscheinen, deren Rückgabetyp ist void.

Neindürfen Sie einen Ausdruck nicht verwenden, selbst wenn er von ist void Typ.

Aus dem Vorwort desselben Dokuments:

Zu den wichtigsten Änderungen in der zweiten Auflage gehörten:

[…]

  • return ohne Ausdruck nicht erlaubt in Funktion, die einen Wert zurückgibt (und umgekehrt)

Dies war also eine Änderung von C89 -> C99 (der zweiten Ausgabe des Sprachstandards) und ist seitdem so geblieben.


C++146.6.3 „Die return Aussage”:

Eine return-Anweisung mit einem Ausdruck vom nicht-void-Typ kann nur in Funktionen verwendet werden, die einen Wert zurückgeben […]
Eine return-Anweisung mit einem Ausdruck vom Typ void kann nur in Funktionen mit dem Rückgabetyp cv void verwendet werden; Der Ausdruck wird ausgewertet, kurz bevor die Funktion zu ihrem Aufrufer zurückkehrt.

Jakönnen Sie einen Ausdruck verwenden wenn es ist vom Typ void (das gilt seit C++98).

  • “Eine return-Anweisung mit einem Ausdruck vom Typ void kann nur in Funktionen mit dem Rückgabetyp cv void verwendet werden.” Warum sollte jemand so einen unsinnigen Code schreiben wollen? Anstatt nur zu schreiben void f2(){ f(); }. Scheint, als müsste es irgendwo eine Begründung dafür geben, obwohl es C++ ist?

    – Ludin

    14. März 2016 um 13:06 Uhr

  • @Lundin: Vorlagen? Ich nehme an. Sieht so aus, als ob <= C99 es auch erlaubt hat, und C++ hat dieses Verhalten wahrscheinlich nur kopiert.

    – DevSolar

    14. März 2016 um 13:06 Uhr


  • @Lundin: In C++ hauptsächlich für Vorlagen. Wenn der Rückgabetyp von f und f2 sind Argumente für die Vorlage, schreiben zu können return f(); ohne Sonderfall void ist praktisch. (offensichtlich dies besondere Beispielcode funktioniert nicht wirklich als Vorlage – aber bei komplexerem Code kann es nützlich sein – siehe die futures Zeug zum Beispiel.

    – Martin Bonner unterstützt Monika

    14. März 2016 um 16:45 Uhr

  • Wie Mohits Antwort korrekt zitiert, befindet sich der Punkt „Rückgabe ohne Ausdruck nicht zulässig in Funktion, die einen Wert zurückgibt“ unter Foreward Paragraph 7 „Major changes in the zweite Ausgabe“ nicht Absatz 6 „Diese dritte Ausgabe … [m]ajor changes”. Zweite Ausgabe war C99, die C89/90 nur für die Rückgabe geändert hat ohne Ausdruck; Rückkehr mit Der Ausdruck in einer void-Funktion war seit C89/90 verboten, als void zum ersten Mal eingeführt wurde. @Lundin vor C99 Rückkehr ohne Ausdruck in a nicht-Void-Funktion und der Aufrufer versucht, den Wert zu verwenden war U.B.

    – dave_thompson_085

    14. März 2016 um 18:45 Uhr


  • Insbesondere in dem Fall, in dem die Funktion synchron ausgeführt wird, wird das Mitglied nur return external_function(args...);

    – Martin Bonner unterstützt Monika

    15. März 2016 um 9:02 Uhr

Benutzeravatar von Mohit Jain
Mohit Jain

Dieser Code ist erlaubt C++ aber nicht reingelassen C

Aus Return-Anweisung @ cpreference

In einer Funktion, die void zurückgibt, kann die return-Anweisung mit Ausdruck verwendet werden, wenn der Ausdruckstyp void ist.


OTOH im C11-Spezifikationsentwurf n1570:

Zu den wichtigsten Änderungen in der zweiten Auflage gehörten:

Rückgabe ohne Ausdruck nicht erlaubt in Funktion, die einen Wert zurückgibt (und umgekehrt)

(return mit Ausdruck nicht erlaubt in Funktion, die a zurückgibt void)

und 6.8.6.4 Rückkehr

Eine Rückgabeanweisung mit einem Ausdruck darf nicht in einer Funktion erscheinen, deren Rückgabetyp ungültig ist. Eine Rückgabeanweisung ohne Ausdruck darf nur in einer Funktion erscheinen, deren Rückgabetyp ungültig ist.

(auch wenn der Ausdruck zu ausgewertet wird void)

  • Besser wäre es, den C++-Standard zu zitieren und evtl. zu dokumentieren, seit welcher Version die Konstruktion erlaubt ist. cpreference ist keine sehr zuverlässige Quelle, viele Codebeispiele haben Fehler.

    – chqrlie

    14. März 2016 um 12:49 Uhr

  • @chqrlie Können Sie mir einen Link zu einer Seite geben, auf der ein Codebeispiel wring @ en.cpreference ist?

    – Mohit Jain

    14. März 2016 um 13:16 Uhr

  • @MohitJain: nur ein Beispiel: en.cppreference.com/w/c/string/byte/strncat kompiliert mit gcc 4.6: main.cpp:31:1: warning: control reaches end of non-void function [-Wreturn-type]. Kein Fehler seit C99, sondern schlechter Stil.

    – chqrlie

    14. März 2016 um 14:03 Uhr

  • @chqrlie Danke. Ich habe keine C++-Spezifikationen, ich verwende die neuesten Entwürfe und en.cppreference als Referenz, wann immer ich sie brauche.

    – Mohit Jain

    14. März 2016 um 16:05 Uhr

  • @MohitJain: Die neuesten C++-Entwürfe sind nah genug dran. Der Quellcode ist tatsächlich auf github verfügbar! Ich wünschte, die C- und C++-Standards wären kostenlos öffentlich verfügbar. cpreference ist eigentlich sehr gut dokumentiert, mein früheres Urteil mag meine Eindrücke aufgrund der französischen Übersetzung widergespiegelt haben. Alle sichtbaren Fehler können behoben werden, sobald sie entdeckt werden.

    – chqrlie

    14. März 2016 um 16:41 Uhr

Benutzeravatar von edmz
edmz

C++ erlaubt so etwas:

void f() 
{
    return void();
}

Während C dies nicht tut. Aus diesem Grund wird eine Warnung ausgegeben, wenn Sie es in ISO C und nicht in ISO C++ kompilieren. Dies wird formal beschrieben als:

Eine return-Anweisung mit einem Ausdruck vom Typ void kann nur in Funktionen mit dem Rückgabetyp cv void verwendet werden

  • Es sieht korrekt aus, aber Standardreferenzen für beide Ansprüche wären schön.

    – HolyBlackCat

    14. März 2016 um 12:46 Uhr

Antti Haapala -- Benutzeravatar von Слава Україні
Antti Haapala – Слава Україні

Der Entwurf des ISO/IEC 9899:201x-Komitees sagt Folgendes:

6.8.6.4 Die return-Anweisung

Einschränkungen

  1. return Anweisung mit einem Ausdruck darf nicht in einer Funktion erscheinen, deren Rückgabetyp ist void.

    EIN return Anweisung ohne Ausdruck darf nur in einer Funktion erscheinen, deren Rückgabetyp ist void.

Also ist es in C verboten.


Sie müssen verwenden -pedantic wechseln zu gcc damit es sich über Standardverstöße beschwert:

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

Benutzeravatar von chqrlie
chqrlie

Standard C unterstützt diese Konstruktion nicht:

C11 6.8.6.4: Die return Aussage

Einschränkungen

1 A return Anweisung mit einem Ausdruck darf nicht in einer Funktion erscheinen, deren Rückgabetyp ist void. EIN return Anweisung ohne Ausdruck darf nur in einer Funktion erscheinen, deren Rückgabetyp ist void.

Für den speziellen Fall in der Frage werden keine besonderen Bestimmungen hinzugefügt. Einige C-Compiler unterstützen dies als Erweiterung (gcc tut, es sei denn, es wird angewiesen, einem der C-Standards zu entsprechen), aber C11 und frühere Versionen betrachten dies als Verletzung einer Einschränkung.

1416210cookie-checkGeben Sie den void-Typ in C und C++ zurück

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy