2009-06-09 12 views
2

Wir alle wissen, dass Hinweise auf Ausnahme werfen schlecht:Pointer-to-Exception Clean-Up

try 
{ 
    ... 
    throw new MyExceptionClass(); 
} 
catch (MyExceptionClass* e) 
{ 
    ... 
} 

Was ist Ihr Ansatz, um die Fang Ziele nach oben in Legacy-Code zu reinigen? Ich vermute, dass ich den ersten Teil beheben durch operator new privat machen:

class MyExceptionClass 
{ 
public: 
    ... 
private: 
    void* operator new(size_t); 
} 

Wie kann ich die Klinke Seite der Dinge machen ebenso hässlich zur Compile-Zeit? Ich will nicht, dass dies in das catch (...) Territorium fällt.

+0

Wie viel des Codes/darf/darf man ändern? Idealerweise würden Sie den Wurfcode und den Fangcode ändern und damit fertig sein. Aber natürlich ist es nicht so einfach. –

+0

Hier geht es teilweise darum, die Orte zu finden, an denen wir die Änderungen vornehmen; Wenn wir anfangen, daran zu arbeiten, haben wir 100% Kontrolle darüber, welchen Code wir ändern können. –

Antwort

2

Wenn ich Sie richtig verstehe, möchten Sie eine schlechte Praxis in einen Kompilierungsfehler verwandeln.

Indem die Ausnahmetyp Nicht-heap-zuweisbaren, haben Sie es geschafft, dies illegal zu machen:

throw new MyExceptionClass(); 

Ach, der nächste Teil nicht, wie Sie es wollen getan werden. Es gibt keine Möglichkeit, den Catch-Block illegal zu machen. Wenn Sie jedoch die Freigabe von MyExceptionClass durch die Heap-Funktion verboten haben, müssen Sie sich keine Gedanken über die Catch-Blöcke machen. Es wird nur verschwendeter Raum sein.

Wenn Sie erzwingen wollen, nicht durch einen Zeiger abzufangen, möchten Sie ein fusselartiges Werkzeug. Ich würde empfehlen, EDoC++ zu betrachten. Es ist ein modifizierter gcc-Compiler, um die korrekte Verwendung der Ausnahme zu überprüfen.

0

ich in der Regel

 
try 
{ 
    throw MyException(); 
} 
catch (const MyException& e) 
{ 
} 

Nicht sicher, aber ich richtig verstehe Ihre Frage.

0

Soweit in C++ - Sprachregeln, können Sie Zeiger auf einen Typ nicht verbieten, der das Aufspüren von Zeigern auf ihnen völlig legal (wie hässlich) macht. Ich würde ein einfaches Werkzeug schreiben, das nach allen catch(T*) Blöcken suchen würde und diese einfach ändern würde.

Ich würde sagen, machen operator new private möglicherweise nicht funktionieren, weil der globale neue Operator möglicherweise noch aufgerufen werden kann. Was ich für Legacy-Codebasen vorschlagen würde, um den Bruch dynamischer Zuordnungen zu erzwingen, wäre, die Signatur des Konstruktors MyExceptionClass zu ändern - oder eine statische Assertion im Standardkonstruktor hinzuzufügen und Kompilierungsfehler zu erzwingen, damit Sie erkennen können, wo diese Standardwerte liegen -constructed MyExceptionClass Typen werden instanziiert.

Ein anderer Ansatz wäre, nach 'throw new' Klauseln zu suchen und nur diese zu beheben.

1

Es klingt wie Sie in der Lage sein möchten, alle Instanzen von throw by pointer nach Wert zu werfen. Du hast einen funktionierenden Klud, um das Werfen mit dem Zeiger zu verhindern. Aber du bist auf der Suche nach einer Möglichkeit, versehentliches Abfangen durch einen Zeiger zu verhindern, sobald alle Würfe geändert wurden.

Soweit ich weiß, kann dies nicht durch die Sprache durchgesetzt werden. Aber ein einfaches sed-Skript nach Instanzen von /catch (.* \*/ suchen sollte gut genug sein, würde ich denken ...

+0

Ja. Ich hatte Angst, das wäre der Fall. Vielen Dank. –

3

Es gibt nichts, was Sie tun können, um das Abfangen durch Zeiger zu verhindern, abgesehen von statischen Analysetools oder Code-Überprüfung. Wenn Sie es jedoch fast unmöglich machen, einen MyExceptionClass Zeiger zu werfen, ist ein catch(MyExceptionClass*) Block ein toter Code.

Um das Werfen mit dem Zeiger vollständiger zu verhindern, müssen Sie tatsächlich etwas mehr Arbeit erledigen.

Ausblenden aller Bedienerformen neu - Siehe here.

Ausblenden des Adressoperators - Das Werfen der Adresse eines zuvor zugewiesenen Objekts hat einige der gleichen Probleme beim Werfen eines Heap-allokierten Objekts.

class MyExceptionClass 
{ 
private: 
    MyExceptionClass* operator&(); 
} 
+0

Ausgezeichneter Punkt; Ich hatte nicht an die Adresse des Betreibers gedacht. –

Verwandte Themen