try, catch hat keine Wirkung?



  • Hallo ich bastel gerade ein wenig mit try und catch, dazu habe ich kleines Beispiel Programm geschrieben:

    #include <iostream>
    #include <math.h> 
    
    using namespace std;
    
    int main()
    {
    	int iZahlen[] = {14, 11, 2, 47, 21 };
    
    	try
    	{
    		cout << iZahlen[6] << endl;
    	}
    	catch(exception ex)
    	{
    		cout << ex.what() << endl;
    	}
    
    	return 0;
    }
    

    Wenn ich das jetzt ausführe stürzt das Programm ab und ich bekomme vom Compiler folgenden Fehler:

    Run-Time Check Failure #3 - The variable 'iZahlen' is being used without being initialized.
    

    Aber müsste er nicht in den catch Block springen?



  • ne, das was da geworfen wird ist keine exception. Das ist nur eine Debug-message. im release-modus stürzts einfach so ab oder gibt müll aus. Wenn du das ganze als vektor machst und iZahlen.at(6) aufrufst, sollte aber eine exception geworfen werden.



  • Achso, danke.
    Aber gibt es keine Möglichkeit auch bei einem Array eine Exception werfen zu lassen?

    Aber bei einem Vector bekomme ich:
    Unknown exception ich finde eine sehr aussagekräftige Meldung ist das..



  • vector wirft nur eine Exception, wenn du mit der Methode at auf die Elemente zugreifst:

    vector<int> v(10);
    ...
    int i = v.at(20) // => std::out_of_range oder wie die heißt, sowas benutzt eigentlich niemand ;)
    

    Zugriffe über Array-Grenzen hinweg (oder beim Vector mit dem [] Operator) erzeugen einfach undefiniertes Verhalten.


  • Administrator

    lord_fritte schrieb:

    Aber gibt es keine Möglichkeit auch bei einem Array eine Exception werfen zu lassen?

    Nein, weil ein Array keine Grössenangaben über sich selber kennt. Das Array ist eigentlich nur ein Speicherblock und mehr nicht. Deshalb muss man sich eigene Konstrukte dazu bauen oder die Standardcontainer verwenden.

    lord_fritte schrieb:

    Aber bei einem Vector bekomme ich:
    Unknown exception ich finde eine sehr aussagekräftige Meldung ist das..

    Bei mir (MSVC 2005) ist die Fehlermeldung auch nicht viel besser:
    "invalid vector<T> subscript"

    Allerdings kann man sich da etwas Abhilfe schaffen:

    std::vector<int> MyVector;
    
    for(int i = 0; i < 10; ++i)
    { MyVector.push_back(i); }
    
    try
    { MyVector.at(11); }
    catch(std::out_of_range& rException) // <- Das ist die eigentliche Exception, welche fliegt.
    { std::cout << "Out of range!" << std::endl; } // <- Eigene Fehlermeldung ausgeben.
    catch(...)
    { std::cout << "Unknown exception!" << std::endl; }
    

    Grüssli



  • Dravere schrieb:

    Bei mir (MSVC 2005) ist die Fehlermeldung auch nicht viel besser:
    "invalid vector<T> subscript"

    Was hättest Du denn gern? Die Meldung sagt doch alles.


  • Administrator

    LordJaxom schrieb:

    Dravere schrieb:

    Bei mir (MSVC 2005) ist die Fehlermeldung auch nicht viel besser:
    "invalid vector<T> subscript"

    Was hättest Du denn gern? Die Meldung sagt doch alles.

    Hast du ein Smilie vergessen? Zum Beispiel so eins -> 🤡
    Wenn nicht und du das wirklich ernst meinst, dann muss ich dir zustimmen, die Meldung sagt wirklich alles. Es könnte x-beliebig was passiert sein. Ein Unknown error wäre genau so gut :p

    Grüssli



  • "Ungültiger Vektorindex". Stimmt, wie kann man das nur verstehen? Da sollte stehen: "Hallo lieber Programmierer, es sieht so aus als hätten Sie versucht auf ein Vektorelement zuzugreifen, das nicht existiert. Soll ich (1) den Vektor entsprechend vergrößern, (2) den Vorgang an Microsoft melden?"


  • Administrator

    Ach du Schande ... Tja, jetzt erkenn ich den Fehler, mein Englisch weisst Lücken auf.
    Subscript heisst Index? Ein Index ist für mich immer noch ein Index, auch im Englischen. Während ein subscript für mich eher ein Script innerhalb eines anderen Scripts ist. Daher verstand ich die Fehlermeldung eher als "Fehler im Code!", was nichtsaussagend wäre.

    Aber man lernt nie aus, danke für die Nachhilfe ^^

    Grüssli



  • Sub\1: An (im Deutschen heißt das Index)
    Super\1: An



  • Kann man mit C++09 den Fehler von ganz oben abfangen?



  • Ich hatte ernsthaft überlegt, wie man die Meldung detaillierter gestalten hätte können - Erwähnung des Index, des Typs, der Methode? Schade, dass es sich nur um ein sprachliches Missverständnis gehandelt hat, denn ich hätte zu allen Gegenargumente gefunden 😃

    Zum Sprachlichen gebe ich aber zu, dass sich mir als COBOL-Vorbelasteter "subscript out of range" bereits mehr oder weniger ins Hirn eingebrannt hat. 🤡



  • danextc++ schrieb:

    Kann man mit C++09 den Fehler von ganz oben abfangen?

    nein. das man das nicht kann und das ist eine bewusste entscheidung. der operator[] soll ein low-level-operator sein, der von der geschwindigkeit her dem aus c gleichwertig sein soll, daher kann man keine bereichsprüfung direkt einbauen und folglich auch nichts werfen. wenn du sicherheit haben willst, benutze die schon erwähnten at()-funktion, dafür gibt es sie.



  • ghorst schrieb:

    danextc++ schrieb:

    Kann man mit C++09 den Fehler von ganz oben abfangen?

    nein. das man das nicht kann und das ist eine bewusste entscheidung. der operator[] soll ein low-level-operator sein, der von der geschwindigkeit her dem aus c gleichwertig sein soll, daher kann man keine bereichsprüfung direkt einbauen und folglich auch nichts werfen. wenn du sicherheit haben willst, benutze die schon erwähnten at()-funktion, dafür gibt es sie.

    Nein, stimmt nicht ganz. Der []-Operator muß keine, aber darf eine Bereichsprüfung vornehmen! Benutze mal MSVC2005 und neuer, dort wird genau das gemacht: die []-Operatoren und Iteratoren machen standardmäßig eine Gültigkeitsprüfung (gehört zur neuer MS-Sicherheitstrategie). Wer das nicht will, muß es explizit abschalten.



  • Schneeflocke schrieb:

    Nein, stimmt nicht ganz. Der []-Operator muß keine, aber darf eine Bereichsprüfung vornehmen!

    Es dürfen auch Dämonen aus der Nase fliegen. Das ist eben undefiniertes Verhalten.





  • Hi,

    nur, weils noch keiner geschrieben hat:

    lord_fritte schrieb:

    ...	catch(exception ex)
    ...
    

    Es gibt verschiedene Gründe, warum man Exceptions besser per Referenz fangen sollte:

    ...	catch(exception& ex)
    ...
    

    Gruß,

    Simon2.



  • lord_fritte schrieb:

    Ja, und das ist auch Sinn der Sache.

    Wenn dein Code so wackelig ist, dass du per Default eine Bereichsprüfung brauchst, dann nimm halt std::vector::at.



  • MFK schrieb:

    Wenn dein Code so wackelig ist, dass du per Default eine Bereichsprüfung brauchst, dann nimm halt std::vector::at.

    Oder lass es noch besser garnicht erst zur Exception kommen sondern frage size() ab und schau ob der Index auf den du zugreifen willst existiert.



  • lord_fritte schrieb:

    Nein - es ist halt nur so, dass man in seinem Programm auch Fehler machen kann, die nicht mittels try/catch erkennbar sind (z.B. bewusst einen "prüfungsfreien" operator[] zu verwenden).
    Irgendwie geht halt nicht Beides: Keine Prüfung haben zu wollen UND gleichzeitig doch vor den eigenen Programmierfehlern geschützt zu sein.
    (OK, für triviale Programme mag das möglich sein)

    Gruß,

    Simon2.


Anmelden zum Antworten