Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: So Apr 28, 2024 23:51

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 24 Beiträge ]  Gehe zu Seite Vorherige  1, 2
Autor Nachricht
 Betreff des Beitrags: Re: C++ Exception-Handling Frage
BeitragVerfasst: Sa Aug 31, 2013 13:17 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2621
Wohnort: Berlin
Programmiersprache: Go, C/C++
Es gibt Software und Hardware Exceptions, Software Exceptions können per Code über
Code:
  1. throw MyException(...);
geworfen werden und diese wir solange weiter gereicht, bis diese verarbeitet wird.
Wenn der Usercode sich nicht drum kümmert, dann passiert dies spätestens im Prozesscode, der vom OS hinzugefügt wird.
Übliche Reaktion ist dann die App zu beenden und eine Fehlermeldung zu bringen.

Hardware Exceptions sind ein Teil der Interruppts und werden seperat in den Prozess übergeben(OS abhänging) und dann wird über die Signal Handler API, vom C++ Standard der Zugriff ermöglicht.
Wenn man Exception support im Compiler hat und diesen anschalten kann, dann werden diese Signals auch als Exception weiter gereicht und man kann sie dann per try catch individuell abfangen.
Exception Support ist in VC++ und GCC C++ verfügbar aber es gibt wohl viele Microcontroller und Consolen Compiler, diesen nicht haben oder nur beschränkt.
Dies ist auch ein Grund, wieso man in der Spielebranche nahezu immer drauf verzichtet.
Ein weiteres Manko an Exceptions ist die Performance, denn der Callstack liegt im Speicher vor aber die Symbole müssen aufgelöst werden und je nach OS und Compiler kann da noch mehr dazu kommen(z.B. Memory Dumps).
Wenn die Exception im Konstruktor passiert, dann kann man sich gleich den Strik holen, da hier das RAII Pattern bei C++98 nicht greifen kann.
Mit C++11 wurden für die Konstruktoren(default, custom und copy) neue Flags eingeführt, die signalisieren, ob dieser eine Exception werfen kann.
Dieser Problematik haben wir folgenden Programmierstiel zu vedanken.
Code:
  1. struct Bla{
  2.     Bla():myPtr(0){}
  3.  
  4.     virtual ~Bla(){if(myPtr) delete myPtr;}
  5.  
  6.     // das verspätete alloziiren verhindert memleaks
  7.     void Init(){if (!myPtr)myPtr = new int;} // workaround um die Construktor Memory leak Problematik
  8.  
  9.     int GetWidth(){
  10.         // Der Nachteil ist offensichtlich, man braucht nun sanity checks da man nicht sicher sein kann, das der user Init aufgerufen hat.
  11.         // PImpl Pattern kann dies auf ein einzigen Sanity check für die ganze Klasse und alle Methoden reduzieren, man braucht nur ein check in der PImpl Klasse. Noch dazu sind PImpl sowie so cool.
  12.         return myPtr?*myPtr:-1;
  13.     }
  14.     private:
  15.         int* myPtr;// wäre es kein Pointer und es ist kein Speicher mehr da, dann wäre es kein Problem, denn der generierte Code geht garnicht erst zum Konstruktor und beendet das Progamm
  16. };
  17.  
  18. struct Blupp:Bla{
  19.     Blupp():Bla()
  20.     // schlechter programmierstiel
  21.     ,myOtherPtr(new int)//wäre hier kein Speicher mehr da würde es kein memleak geben, denn bisher wurde kein dynamischer Speicher alloziiert und ~Bla() würde aufgerufen werden
  22.  
  23.     ,myArray(new int[10]){}//keiner Speicher mehr da für die allokation, nun ist myOtherPtr ein memleak, myArray aber nicht.
  24.    
  25.     Blupp(int width)():Bla()
  26.     ,myArray(0)
  27.     ,MyOtherPtr(new int){// wir gehen davon aus es ist genug speicher da und der default constructor läuft durch
  28.         ration = 100 / width;// width == 0 und MyOtherPtr wird dank Hardware Exception leaken.
  29.     }
  30.  
  31.     virtual ~Blupp(){
  32.         if (myOtherPtr) delete myOtherPtr;
  33.         if (myArray) delete[] myArray;
  34.     }
  35.     private:
  36.         int ratio;
  37.         int* myArray;
  38.         int* myOtherPtr;
  39. };


Ich verwende RAII, PImpl und ErrorCodes, sowie überschriebene Signal Handler.

Bei Linearer Algebra kann man auf Infinity und 0 Prüfen und Formeln kann man in der Regel so umstellen, dass sie diese Problematiken umgehen. Man muss sich da allerdings einmal mit floating point compare auseinander setzen, denn if (bla==0.0) ist die falsche Lösung.

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Zuletzt geändert von TAK2004 am Sa Aug 31, 2013 20:30, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: C++ Exception-Handling Frage
BeitragVerfasst: Sa Aug 31, 2013 14:04 
Offline
DGL Member

Registriert: Sa Apr 14, 2012 14:28
Beiträge: 52
Programmiersprache: c++
TAK2004 hat geschrieben:
Bei Linearer Algebra kann man auf Infinity und 0 Prüfen und Formeln kann man in der Regel so umstellen, dass sie diese Problematiken umgehen. Man muss sich da allerdings einmal mit floating point compare auseinander setzen, denn if (bla==0.0) ist die falsche Lösung.


Ich muss ja sagen, es ist schrecklich und faszinierend zugleich deine Beiträge zu lesen. Schrecklich weil man immer wieder was vorgesetzt bekommt, was man noch nicht weiß und erstmal recherchieren muss -.- Faszinierend weil man was lernt...

Auf die zitierte Stelle bezogen, meinst du damit, dass dass -0.0 und 0.0 nicht das selbe sind? Wenn ja, kann ich das mit abs() abfangen?

MfG DerTr0ll


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: C++ Exception-Handling Frage
BeitragVerfasst: Sa Aug 31, 2013 14:18 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 588
Programmiersprache: C++
Der Troll hat geschrieben:
Auf die zitierte Stelle bezogen, meinst du damit, dass dass -0.0 und 0.0 nicht das selbe sind? Wenn ja, kann ich das mit abs() abfangen?

0.0f und -0.0f sind zwar, wenn man Bit für Bit vergleicht, nicht gleich. Habe aber gerade mal folgendes ausprobiert:
Code:
  1. int main(int argc, char* argv[])
  2. {
  3.   const float f = -0.0f;
  4.   if(f == 0.0f)
  5.     cout << "gleich";
  6.   return 0;
  7. }

Das "gleich" wird dabei ausgegeben. Der Vergleichsoperator weiß also offenbar um die semantische Äquivalenz.

@TAK: Dein Code ist wirklich schwer lesbar, wenn du keine Einrückung verwendest.

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Zuletzt geändert von glAwesome am So Nov 17, 2013 20:28, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: C++ Exception-Handling Frage
BeitragVerfasst: Sa Aug 31, 2013 14:33 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Nein, ich denke es geht eher um sowas (für Doubles):
Code:
  1. >>> 1/1e-310
  2. inf


Will sagen, man kann auch mit Zahlen ungleich null in der Division ein unendliches Ergebnis bzw. einen Overflow produzieren.

grüße

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: C++ Exception-Handling Frage
BeitragVerfasst: Sa Aug 31, 2013 14:51 
Offline
DGL Member

Registriert: Sa Apr 14, 2012 14:28
Beiträge: 52
Programmiersprache: c++
ah... okay... also sollte man Fälle die aus dem Wertebereich eines Variablentyps fallen auch noch aufpassen... sprich alles was inf erzeugt.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: C++ Exception-Handling Frage
BeitragVerfasst: Sa Aug 31, 2013 20:28 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2621
Wohnort: Berlin
Programmiersprache: Go, C/C++
Ich muss zugeben, dass es viel zu lesen war und ich leider nicht soviel Zeit hatte, weil ich noch zu nem Termin musste.
Das Problem bei floatingpoint also float und double ist die Darstellung und Präzision.
Um korrekt zu vergleichen braucht man sowas.
Code:
  1. template<class T>
  2. bool CompareFloatingpoint<>(const T a, const T b){
  3.   return (a-b) < numeric_limits<T>::epsilon();
  4. }


edit:
Code:
  1. bool isTrue = CompareFloatingpoint(-0,0);// (-0)-0 -> 0 < EPSILON == true
  2. bool isFalse = CompareFloatingpoint(9,800000-799991);// die Ungenauigkeit ist größer als EPSILON, hier sollte man ander testen bzw. die Rechnung mal überdenken ;)
  3. bool isTrue = CompareFloatingpoint(0.00000001,0.000000009);// EPSILON ist viel zu groß und alles wird in dem Bereich als korrekt bedacht
  4.  

Daher sollte man nicht immer EPSILON benutzten, das geht für viele Sachen gut aber sauber ist es, wenn man EPSILON für die jeweilige Zahlengröße benutzt.
Also wenn ich 9999999999-1 Rechne, dann sollte man EPSILON von 9999999999 verwenden.
Sehr genau erklärt es folgender Artikel.
http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
edit end:

Dann kommt noch die Problematik, dass es negInf, posInf, negNull, posNull gibt und float und double kann man auch nicht ohne weiteres vergleichen, erst sollte man konvertieren und dann das entsprechende epsilon verwenden.
Epsilon ist der kleinst mögliche Wertunterschied auf ausgeführten CPU.
Bzgl der Problematik zu Floatingpoint und comparement sowie floatingpoint und Exceptions kann ich folgende Seite empfehlen.
Krasser Valve Programmierer Blog

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Zuletzt geändert von TAK2004 am So Sep 01, 2013 21:40, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: C++ Exception-Handling Frage
BeitragVerfasst: So Sep 01, 2013 20:41 
Offline
DGL Member
Benutzeravatar

Registriert: So Sep 26, 2010 12:54
Beiträge: 238
Wohnort: wieder in Berlin
Programmiersprache: Englisch
""Smart"Pointer" kann man in Delphi übrigens auch ganz gut "nachbauen".

In der Regel benutzt man dafür interfaces.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: C++ Exception-Handling Frage
BeitragVerfasst: Di Sep 03, 2013 10:06 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2621
Wohnort: Berlin
Programmiersprache: Go, C/C++
Ich hab bisher keine Smartpointer gebraucht, ich verwende RAII Pattern für Speicher.
Da gibt es bei mir 4 Klassen, class AutoPointer<T>, class AutoPointerArray<T>, class AutoPointerReference<T> und class AutoPointerArrayReference<T>.
Die ersten beiden Klassen sind die eigentlichen Klassen, welche RAII implementieren und die letzten beiden sind Helferklassen, die RAII umgehen und erlauben, den pointer in andere Scopes zu tragen.
Wenn dann der erste Scope aus läuft, dann wird der Speicher nicht frei gegeben, weil dieser den Owner, per Helferklasse an eine andere Instanz von AutoPointer oder AutoPointerArray weiter gegeben hat.

Einziger Nachteil ist, man hat weniger Informationen, wer denn so diesen Speicher verwendet aber das bis dato nie Interessant.
Bei meiner String Klasse kann man auch Pointer übergeben aber man muss dann auch die MemoryManagment Policy mit angeben.
Default ist es Copy aber für const char* also strings die im Code stehen benutzte ich Unmanaged und damit geht der String davon aus, dass er den Speicher nicht ändern und frei geben darf.
Dann gibt es TakeOwnership um z.B. strings zu übernehmen, welche von irgendeiner API generiert wurde und vom user frei gegeben werden muss(z.B. OS-API's).

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: C++ Exception-Handling Frage
BeitragVerfasst: Di Sep 03, 2013 20:31 
Offline
DGL Member
Benutzeravatar

Registriert: So Sep 26, 2010 12:54
Beiträge: 238
Wohnort: wieder in Berlin
Programmiersprache: Englisch
das klingt alles immer alles so... wichtig :)


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 24 Beiträge ]  Gehe zu Seite Vorherige  1, 2
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 19 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.030s | 17 Queries | GZIP : On ]