return Anweisung optional?

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
Benutzeravatar
fat-lobyte
Beiträge: 1398
Registriert: Sa Jul 05, 2008 12:23 pm
Wohnort: ::1
Kontaktdaten:

return Anweisung optional?

Beitrag von fat-lobyte » Do Sep 11, 2008 6:46 pm

Hallo!
Bitte seht euch folgenden Code an:

Code: Alles auswählen

#include <iostream>
#include <string>

std::string getMessage()
{
    std::string msg("Is there anybody out there?");
}

int main()
{
    std::string message(getMessage());
    std::cout<<message<<'\n';

    return 0;
}
Wenn ihr mal etwas genauer hinseht werdet ihr bemerken, dass da etwas fehlt, und zwar es ist die "return msg;" anweisung in der Funktion getMessage(). "Das ist doch klar ein Fehler" werdet ihr denken. Die funktion getMessage() deklariert, dass sie ein Objekt des Typs std::string zurückgibt, aber das tut sie offensichtlich nicht. Die logische schlussfolgerung wäre, dass der Compiler einen fehler ausspuckt, so in die richtung von "Missing return statement in function getMessage()" (oder so ähnlich).

Tja, wenn man den Code durch den Compiler schickt, gibt erstmal ne Überraschung: der Compiler gibt keine Fehler aus, und kompiliert das Programm.
Wenn man das Programm aufruft gibts dann eine Endlosschleife (zumindest bei mir, bei vielen gibts wahrscheinlich einen Segmentation Fault.), und es lässt sich nur durch CTRL- C beenden.

Kann mir jemand sagen was da los ist? Offensichtlich holt sich der Konstruktur von std::string (erste Zeile in main() ) fröhlich seinen String vom Stack ab, nachdem er den Aufruf nach getMessage() getätigt hat. getMessage() hat dort aber nichts abgelegt, also ist der Inhalt dieses Strings undefiniert, und so verursacht auch der Konstruktoraufruf undefiniertes verhalten.

Aber wieso in aller Welt gibt es da keinen Fehler? Ist das ein Compilerproblem? Irgendwie entzieht sich das meiner Weisheit.

Verwendete Compiler: gcc-4.3, gcc-4.4 aus SVN, beide male das gleiche ergebnis.

Ich bitte um Hilfe, mein Welt (C++) Bild wieder zurechtzurücken.
Haters gonna hate, potatoes gonna potate.

Benutzeravatar
Kerli
Beiträge: 1456
Registriert: So Jul 06, 2008 10:17 am
Wohnort: Österreich
Kontaktdaten:

Re: return Anweisung optional?

Beitrag von Kerli » Do Sep 11, 2008 8:59 pm

fat-lobyte hat geschrieben:Tja, wenn man den Code durch den Compiler schickt, gibt erstmal ne Überraschung: der Compiler gibt keine Fehler aus, und kompiliert das Programm.
Also ich bekomm da zumindest eine Warnung, dass der Kontrollfluss das Ende einer Nicht-void-Funktion erreicht.
fat-lobyte hat geschrieben:Wenn man das Programm aufruft gibts dann eine Endlosschleife (zumindest bei mir, bei vielen gibts wahrscheinlich einen Segmentation Fault.), und es lässt sich nur durch CTRL- C beenden.
Bei mir gibt es dann zwar keine Endlosschleife, dafür aber eine sonderbare Ausgabe, die wahrscheinlich den Inhalt irgendwelcher Speicherstellen ausgibt.

Warum das so ist kann ich mir irgendwie auch nicht erklären.
"Make it idiot-proof and someone will invent an even better idiot." (programmers wisdom)

OpenGL Tutorials und vieles mehr rund ums Programmieren: http://www.tomprogs.at

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8859
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: return Anweisung optional?

Beitrag von Xin » Do Sep 11, 2008 9:36 pm

Du benutzt den GCC, nehme ich an.

Ich sehe hier einen Compilerfehler, begründet durch die Krankheit, die man in den Standard gekotzt hat:
Es muss int main( void ) heißen, aber man darf das return <integer> in main weglassen.

Hier sollte definitiv eine Fehlermeldung kommen.
Mit dem GCC erhalte ich einen SegFault, wie zu erwarten war.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Benutzeravatar
fat-lobyte
Beiträge: 1398
Registriert: Sa Jul 05, 2008 12:23 pm
Wohnort: ::1
Kontaktdaten:

Re: return Anweisung optional?

Beitrag von fat-lobyte » Fr Sep 12, 2008 7:53 am

Kerli hat geschrieben:
fat-lobyte hat geschrieben:Tja, wenn man den Code durch den Compiler schickt, gibt erstmal ne Überraschung: der Compiler gibt keine Fehler aus, und kompiliert das Programm.
Also ich bekomm da zumindest eine Warnung, dass der Kontrollfluss das Ende einer Nicht-void-Funktion erreicht.
Das ist schon mal etwas. Darf man fragen mit welchen Flags du kompiliert hast? Ich habe nämlich keine hinzugefügt, und bei mir kam nicht mal ne Warnung.
Xin hat geschrieben:Ich sehe hier einen Compilerfehler, begründet durch die Krankheit, die man in den Standard gekotzt hat:
Es muss int main( void ) heißen, aber man darf das return <integer> in main weglassen.
Also du meinst, das kommt von der Tatsache, dass man in main() die return anweisung weglassen kann? Ich dachte immer, main() sei so eine art Spezialfall, der mit "Compiler Magic" gelöst werden sollte.

Könnte das vielleicht auch jemand mit einem nicht- GCC bestätigen? Ich würd gern wissen, wie andere Compiler das handhaben.
Haters gonna hate, potatoes gonna potate.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8859
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: return Anweisung optional?

Beitrag von Xin » Fr Sep 12, 2008 8:55 am

fat-lobyte hat geschrieben:Das ist schon mal etwas. Darf man fragen mit welchen Flags du kompiliert hast? Ich habe nämlich keine hinzugefügt, und bei mir kam nicht mal ne Warnung.
Keine Flags.
Das spielt aber imho auch keine Rolle. Der Code, den Du geschrieben hast, darf m.E. nicht kompiliert werden, weil er syntaktisch falsch ist.
fat-lobyte hat geschrieben:
Xin hat geschrieben:Ich sehe hier einen Compilerfehler, begründet durch die Krankheit, die man in den Standard gekotzt hat:
Es muss int main( void ) heißen, aber man darf das return <integer> in main weglassen.
Also du meinst, das kommt von der Tatsache, dass man in main() die return anweisung weglassen kann? Ich dachte immer, main() sei so eine art Spezialfall, der mit "Compiler Magic" gelöst werden sollte.
main() ist ein Spezialfall.
Spezialfälle deuten auf ein Designproblem hin (welches hier absolut gegeben ist) und Spezialfälle weichen vom gut getesteten Regelfall ab, was bedeutet, dass man Ausnahmen in der Regel in den Spezialfällen findet.

Bei der Entwicklung von Genesys spare ich mir Code und Testfälle, in dem ich auf Spezialfälle verzichte. Das widerrum kostet sehr viel Zeit, denn man muss erstmal allgemein akzeptiertes und hysterisch gewachsenes in Frage stellen, zum Beispiel:

Code: Alles auswählen

int add( int a, int b )
  return a+b;                  // geht nicht

int main( int argc, char ** argv )
{
  if( argc > 2 ) 
    return add( argc, 4711 );  // geht
}
fat-lobyte hat geschrieben:Könnte das vielleicht auch jemand mit einem nicht- GCC bestätigen? Ich würd gern wissen, wie andere Compiler das handhaben.
Visual Studio 2005 Professional: error C4716: 'getMessage': Muss einen Wert zurückgeben
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Benutzeravatar
fat-lobyte
Beiträge: 1398
Registriert: Sa Jul 05, 2008 12:23 pm
Wohnort: ::1
Kontaktdaten:

Re: return Anweisung optional?

Beitrag von fat-lobyte » Fr Sep 12, 2008 9:33 am

Xin hat geschrieben:
fat-lobyte hat geschrieben:Könnte das vielleicht auch jemand mit einem nicht- GCC bestätigen? Ich würd gern wissen, wie andere Compiler das handhaben.
Visual Studio 2005 Professional: error C4716: 'getMessage': Muss einen Wert zurückgeben
Interessant, vielleicht sollte man eine GCC- Mailing Liste kontaktieren, und fragen was die dazu meinen.
Haters gonna hate, potatoes gonna potate.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8859
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: return Anweisung optional?

Beitrag von Xin » Fr Sep 12, 2008 9:41 am

fat-lobyte hat geschrieben:Interessant, vielleicht sollte man eine GCC- Mailing Liste kontaktieren, und fragen was die dazu meinen.
War das verwunderlich?

Vielleicht sollte man einfach eine Mail an gcc-bugs(at)gnu.org (oder wie die Adresse lautet) senden...
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Benutzeravatar
fat-lobyte
Beiträge: 1398
Registriert: Sa Jul 05, 2008 12:23 pm
Wohnort: ::1
Kontaktdaten:

Re: return Anweisung optional?

Beitrag von fat-lobyte » Fr Sep 12, 2008 10:46 am

Ok, also ich hab mich mal ein bisschen in das Problemchen vertieft.

Der C++ Standard sagt nichts genaues darüber aus, ob eine Funktion ein Return statement haben muss.
In Kapitel 8.4 steht zwar, dass eine Funktionsdefinitions einen Funktionskörper besitzen muss, dieser Funktionskörper ist aber per Definition nur eine Ansammlung von Statements in Geschweiften Klammern.

Es gibt zwar regeln, wie mit Return Statements verfahren werden muss.
Beispielsweise in Kapitel 6.6.3, Absatz 2, wo steht dass ein return statement bei Funktionen die void zurückgeben keinen parameter enthalten darf, und ein return statement bei nicht- void funktionen einen Parameter haben muss,
oder die behandlung von return statements in Konstruktoren, Destruktoren und Try/Catch blöcken.

Einen expliziten zwang zu einem Return statement habe ich nicht gefunden, hier hat sich das Komitee wahrscheinlich auf das "Common Sense" der Compilerentwickler verlassen - anscheinend vergebens.

Das einzige was damit zu tun hat ist, dass in Kapitel 3.6.5 Absatz 5 explizit drinnensteht, dass wenn main() kein return statement besitzt, es das gleiche bedeutet wie wenn "return 0;" stehen würde.

Kurz gesagt: der Standard schreibt nichts vor, und GCC Compiler erlaubt die return statements auch wegzulassen.


Es gibt zwar einen 9 Jahre alten Patch für den GCC (der schon integriert wurde), dass eine Warnung für unerreichbare Statements ausgegeben wird, aber das gilt nur für so sachen wie

Code: Alles auswählen

if (something)
    return 0;
Ich werde mal auf irgend einer GCC mailing Liste oder Newsgroup fragen, was da los ist.


Falls sich jemand für meine Nachforschungen interessiert:

ISO/IEC 14882/1998
3.6.5 § 5 - Rückgabewert von main
6.6.3 § 2 - Return Statement
8.4 - Funktionsdefinitionen

http://gcc.gnu.org/ml/gcc-patches/1999-11/msg00731.html - Patch für das Warning
http://www.network-theory.co.uk/docs/gc ... ro_94.html - Fehler oder Warnmeldungen

[edit]Den standard kann man für Geld bei diversen Webseiten herunterladen. Ich bin mir sicher, wer suchet der findet. Also einfach mal ISO/IEC 14882 in google eingeben, vielleicht gibts dann auch noch das ein oder andere Gratis -exemplar.[/edit]
Haters gonna hate, potatoes gonna potate.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8859
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: return Anweisung optional?

Beitrag von Xin » Fr Sep 12, 2008 10:53 am

fat-lobyte hat geschrieben:Falls sich jemand für meine Nachforschungen interessiert:
Für das Ergebnis interessiere ich mich.

Das Programm ist bei mir mit SegFault abgeschmiert, weil es natürlich Blödsinn ist.
Ob die GCC Entwickler das für akzeptabel halten, halte ich schon für interessant.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Antworten