mikrocontroller.net

Forum: PC-Programmierung throw ausm konstruktor einer global erzeugten variable


Autor: daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo C++ Experten,

struct X {
    X(int i) throw(std::runtime_error) : i(i) {
        if(i==0)
            throw std::runtime_error("blabla");
    }
    int i;
}x(0);

int main() {
}



Ich sehe keine Möglichkeit hier die Exception abzufangen, oder?
Ausser in Konstruktor selbst natürlich.
Verbietet Standard sowas überhaupt?
Exception ausm Konstruktor schmeissen ist glaube ich erlaubt.

Grüsse und schönen Sonntag Euch.

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Standard verbietet das nicht.

Da die Ausnahme in der Initialisierungsphase auftritt, in der noch kein 
catch im eigenen Code greifen kann, wird sie vom Startup-Code der RTL 
oder vom Betriebssystem behandelt - ein Absturz bevor noch main gerufen 
ist wird die Folge sein.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ich sehe keine Möglichkeit hier die Exception abzufangen, oder?
> Ausser in Konstruktor selbst natürlich.

Du kannst höchstens davon ableiten und im Konstruktor der abgeleiteten 
Klasse die Exception fangen.

> wird sie vom Startup-Code der RTL

Was hat das Fernsehen damit zu tun?

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rolf Magnus wrote:

> Du kannst höchstens davon ableiten und im Konstruktor der abgeleiteten
> Klasse die Exception fangen.

Das wird nicht funktionieren, denn dazu müßte man den vom Compiler 
implizit generierten Aufruf des Konstruktors in einen try-Block 
einschließen. Das läßt jedoch die C++ - Syntax nicht zu.

Bei Variablen auf Modullevel ist da nichts zu machen - außer den 
Startup-Code zu modifizieren, oder selbst zu schreiben. Wieviel Sinn das 
macht, kann sich jeder selbst überlegen...

>
>> wird sie vom Startup-Code der RTL
>
> Was hat das Fernsehen damit zu tun?

RTL = RunTimeLibrary

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Das wird nicht funktionieren, denn dazu müßte man den vom Compiler
> implizit generierten Aufruf des Konstruktors in einen try-Block
> einschließen.

Genau.

> Das läßt jedoch die C++ - Syntax nicht zu.

Das ist Unsinn. Man kann die Exception fangen, aber sie wird automatisch 
wieder geworfen. Das kann man meines Wissens nicht verhindern.
Um mal das Originalbeispiel aufzugreifen:
#include <iostream>
#include <stdexcept>

struct X {
    X(int i) throw(std::runtime_error) : i(i) {
        if(i==0)
            throw std::runtime_error("blabla");
    }
    int i;
};

struct Y : public X
{
    Y(int i)
    try
        : X(i)
    {
    }
    catch (std::exception& ex)
    {
        std::cout << "Ausnahme gefangen: " << ex.what() << '\n';
    }
};

Y y(0);

int main() {
}

>>> wird sie vom Startup-Code der RTL
>>
>> Was hat das Fernsehen damit zu tun?
>
>RTL = RunTimeLibrary

Ach die CRT ;-)

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Das kann man meines Wissens nicht verhindern.

Also nützen die ganzen Komplikationen in dem Fall nichts. Es macht ja 
schließlich keinen Sinn, ein Objekt als konstruiert zurückzugeben, bei 
dem ein Konstruktor einer Basisklasse gescheitert ist.

Exceptions in Konstruktoren sind ein heikles Thema - wenn man nicht 
aufpaßt, produziert man damit ein Speicherleck nach dem anderen.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Also nützen die ganzen Komplikationen in dem Fall nichts.

Naja, du kannst die Exception auswerten und darauf reagieren. Du kannst 
sie aber nicht unter den Teppich kehren.

> Es macht ja schließlich keinen Sinn, ein Objekt als konstruiert
> zurückzugeben, bei dem ein Konstruktor einer Basisklasse gescheitert
> ist.

Das ist vermutlich auch der Grund, warum die Exception dann in jedem 
Fall weitergeworfen wird.

> Exceptions in Konstruktoren sind ein heikles Thema - wenn man nicht
> aufpaßt, produziert man damit ein Speicherleck nach dem anderen.

Allerdings sind sie auch die einzige Möglichkeit (abgesehen von 
zusätzlichen Membervariablen, die man später prüfen kann), um aus dem 
Konstruktor heraus einen Fehler zu melden.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.