Heftige Reaktion bei kleinem Schnitzer...



  • Folgender Code [Ausschnitt]

    // Das sind nur 2 Klassen + 1 Funktion
    class Relatives {
    public:
        std::string first;
        std::string second;
        std::vector <std::string> exc;
        std::string flag;
    };
    class ParseResult {
    public:
        std::vector<Relatives> Relate;          //-r -f -e
        std::vector<std::string> Filter;        //-o
        std::vector<std::string> ListAlways;    //-a
        std::vector<std::string> RepairFlagged; //-m
        std::vector<std::pair<std::string, std::string> > Declarations; //-d
    
        ParseResult()
            :Relate(), Filter(), ListAlways(), RepairFlagged(), Declarations()
        {
        }
    };
    
    ParseResult run_comparison_script(const std::string& script) {}
    
    int main() {
        run_comparison_script("does not matter"); // bye bye Programm
        return 0;
    }
    

    führt bei eine leerem Funktionsrumpf von "run_comparison_script" (sprich KEIN RETURN) zum Absturz (benimmt sich wie eine Endlosschleife)

    Das sowas dabei passieren kann ist mir neu...
    (Ich habe es extra in einem neuen Projekt geprüft).

    Mit dem Debugger bleibe ich im Destruktor von std::pair kleben.



  • Ja, so ist das. Es gibt keine kleinen Fehler 😉



  • Wo issen jetzt der Fehler genau?



  • Das dürfte doch gar nicht kompilieren ohne return. WTF.



  • Es wird "nur" gewarnt.





  • void return schrieb:

    Das dürfte doch gar nicht kompilieren ohne return. WTF.

    Doch. Es ist nur UB.

    N3337 §6.6.3/2 schrieb:

    Flowing off the end of a function is equivalent to a return with no value; this results in undefined
    behavior in a value-returning function.



  • Tim06TR schrieb:

    Es wird "nur" gewarnt.

    Jo, schließlich ist das Programm nicht ill-formed...



  • Haben die das in C++11 immer noch nicht gefixt?



  • c++ölf schrieb:

    Haben die das in C++11 immer noch nicht gefixt?

    Siehst du doch. Und ich glaube, das kommt auch nicht im C++14 Std...



  • macht es denn irgendeinen sinn das das nicht zum compilerfehler führt?



  • 😕 Wenn ich den gezeigten Quellcode in MSVC 2012 ausführe bekomme ich:

    1 Error: error C4716: 'run_comparison_script' : must return a value
    1 Warning: warning C4100: 'script' : unreferenced formal parameter

    Was verwendet ihr den für einen Compiler?



  • GCC.



  • Sone schrieb:

    GCC.

    Dann mal +1 für MSVC 😃



  • War ja klar...Billigcompiler.



  • out schrieb:

    Sone schrieb:

    GCC.

    Dann mal +1 für MSVC 😃

    Lol. Dafür das er mit dem Standard inkompatibel ist? 👎

    GCC tut nur seine Pflicht :p



  • Darf ein Compiler nur als Fehler auslegen, was tatsächlich durch den Standard untersagt ist?



  • Wenn ich mich nicht taeusche, darf nur einen Fehler ausgeben, was wirklich ill-formed ist. Das Programm ist ja Standard-Konform, wenn auch mit undefiniertem Verhalten, also muss es kompilieren. Warnen dagegen darf ein Compiler so viel er will.

    In der Hinsicht hat MSVC hier wirklich einen Bug:

    #include <iostream>
    
    void foo()
    {
    	int i;
    	i = (++i)*(--i)%60;
    	std::cout << i;
    }
    
    int bar()
    {
    	int i;
    	i = (++i)*(--i)%60;
    	return i;
    }
    
    int retNoValue1()
    {}
    
    int retNoValue2()
    {
    	foo();
    }
    
    int retNoValue3()
    {
    	if(bar() % 8)
    	{
    		return 0;
    	}
    }
    
    int main()
    {
    	retNoValue1();
    	retNoValue2();
    	retNoValue3();
    }
    
    1>------ Erstellen gestartet: Projekt: Test, Konfiguration: Debug Win32 ------
    1>Der Buildvorgang wurde am 28.10.2012 09:48:03 gestartet.
    1>InitializeBuildStatus:
    1>  Aktualisieren des Timestamps von "Debug\Test.unsuccessfulbuild".
    1>ClCompile:
    1>  main.cpp
    1>p:\tmp\test\main.cpp(6): warning C4700: Die nicht initialisierte lokale Variable "i" wurde verwendet.
    1>p:\tmp\test\main.cpp(13): warning C4700: Die nicht initialisierte lokale Variable "i" wurde verwendet.
    1>p:\tmp\test\main.cpp(18): error C4716: 'retNoValue1': Muss einen Wert zurückgeben
    1>p:\tmp\test\main.cpp(23): error C4716: 'retNoValue2': Muss einen Wert zurückgeben
    1>p:\tmp\test\main.cpp(31): warning C4715: "retNoValue3": Nicht alle Steuerelementpfade geben einen Wert zurück.
    1>
    1>Fehler beim Erstellen
    1>
    1>Verstrichene Zeit 00:00:00.79
    ========== Erstellen: 0 erfolgreich, Fehler bei 1, 0 aktuell, 0 übersprungen ==========
    

    Bei den uninitialisierten Variablen warnt er erwartungsgemaess, auch bei retNoValue3 warnt er richtig. Aber bei retNoValue1 und retNoValue2 ist der Fehler falsch, weil das trotzdem nicht ill-formed ist.
    Getestet auf MSVC 2010 Professional, deaktivieren der MS-Spracherweiterungen macht keinen Unterschied. VS2012 kann ich grad nicht benutzten, weil mir gestern durch einen Stromausfall eine Platte abgeraucht ist (nach nicht mal 48 h Betrieb, hatte meinen PC gerade vom aufruesten wieder :(). Koennt das mal jemand anderes testen, obs da richtig geht?



  • Ich finde es aber ehrlich gesagt angemessen, dass er nicht kompiliert. Es gibt doch wirklich keinen Fall, wo das sinnvoll sein könnte.



  • Natuerlich waere es absolut nicht sinnvoll, wuerde es kompilieren. Tatsache ist aber, dass das Programm nicht ill-formed ist, weshalb der Compiler C4716 eigentlich genauso als Warnung behandlen muesste wie C4715. Ob ich dann 'Warnungen wie Fehler behandeln' anschalte ist meine Sache.


Log in to reply