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


von daniel (Gast)


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.

von Uhu U. (uhu)


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.

von Rolf Magnus (Gast)


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?

von Uhu U. (uhu)


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

von Rolf Magnus (Gast)


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:
1
#include <iostream>
2
#include <stdexcept>
3
4
struct X {
5
    X(int i) throw(std::runtime_error) : i(i) {
6
        if(i==0)
7
            throw std::runtime_error("blabla");
8
    }
9
    int i;
10
};
11
12
struct Y : public X
13
{
14
    Y(int i)
15
    try
16
        : X(i)
17
    {
18
    }
19
    catch (std::exception& ex)
20
    {
21
        std::cout << "Ausnahme gefangen: " << ex.what() << '\n';
22
    }
23
};
24
25
Y y(0);
26
27
int main() {
28
}

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

Ach die CRT ;-)

von Uhu U. (uhu)


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.

von Rolf Magnus (Gast)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.