Bezpieczeństwo wyjątków w C++: OpenGL

Slides:



Advertisements
Podobne prezentacje
C++ wykład 2 ( ) Klasy i obiekty.
Advertisements

C++ wykład 4 ( ) Przeciążanie operatorów.
C++ wykład 7 ( ) Wyjątki.
Programowanie obiektowe
Klasa listy jednokierunkowej Przekazywanie parametrów do funkcji
Dzisiejszy wykład Wyjątki.
Programowanie obiektowe PO PO - LAB 4 Wojciech Pieprzyca.
Standardowa biblioteka języka C++
Wskaźniki repetytorium Wskaźniki int Y = 1, X = 2; X = 5; int *p = &X; Y X p 4 4 p = &Y; *p = 4; 5.
Klasy i obiekty.
Wzorce.
Obiektowe metody projektowania systemów Design Patterns STRATEGY.
Dziel – Rządź - Złącz.
Szablony (wzorce) Przykład 1: Szablon klasy -
OOPC++ - wstêp, klasy1 Klasy Do struktury można dołączyć operacje działające na jej polach. struct date { int day, month, year; void set (int d, int m,
Licznik template<class Count_Type> class Count { public:
Bartosz Walter Inżynieria oprogramowania Lecture XXX JavaTM – część II Bartosz Walter
Obiektowe metody projektowania systemów
Obiektowe metody projektowania systemów Command Pattern.
C++ wykład 2 ( ) Klasy i obiekty.
C++ wykład 7 ( ) Wyjątki. Ogólne spojrzenie na wyjątki Wyjątki zaprojektowano do wspierania obsługi błędów. System wyjątków dotyczy zdarzeń synchronicznych.
Wykład 1: Wskaźniki Podstawy programowania Programowanie w C
Czytanie, pisanie i rysowanie – cd.. Jeszcze jeden strumyk PrintStream działa jak PrintWriter, ale: Używa domyślnego (systemowego) kodowania Nie wyrzuca.
Techniki programowania gier
Język C# Copyright, 2004 © Adam Czajka.
Podstawy C# Grupa .NET PO.
Podstawy programowania II
Programowanie obiektowe III rok EiT
Programowanie urządzeń mobilnych – wykład IV
Podstawy informatyki 2013/2014
Java 3 MPDI Programowanie obiektowe W7. import java.io.*; public class X { // kontrukcja throws – określenie jakie wyjątki może dana metoda // sygnalizować
Jerzy F. Kotowski1 Informatyka I Wykład 11 STRUKTURY I UNIE.
Programowanie obiektowe w C++
Programowanie obiektowe III rok EiT
Programowanie obiektowe III rok EiT
Seminarium problemowe
Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/21 Dariusz Wardowski.
Programowanie obiektowe Wykład 7 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/20 Dariusz Wardowski.
Programowanie obiektowe Wykład 6 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/14 Dariusz Wardowski.
C# Platforma .NET CZ.3 Kuba Ostrowski.
Podstawy informatyki 2013/2014 Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi.
Kurs języka C++ – wykład 3 ( )
Kurs języka C++ – wykład 8 ( )
Kurs języka C++ – wykład 9 ( )
K URS JĘZYKA C++ – WYKŁAD 7 ( ) Wyjątki.
Programowanie strukturalne i obiektowe C++ Przeładowanie operatorów Robert Nowak.
Kurs języka C++ – wykład 4 ( )
Technologie internetowe Wykład 7 Kontrola danych użytkownika.
K URS JĘZYKA C++ – WYKŁAD 2 ( ) Klasy i obiekty.
Programowanie obiektowe Wykład 9 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/15 Dariusz Wardowski.
1 dynamiczny przydział pamięci malloc() free() realloc() calloc() memset() memcpy( ) mempcpy( ) memmove() (wskaźniki!! )
Wyjątki. Po co nam wyjątki? Często pisząc jakiś kod staramy się go uczynić uniwersalnym, jesteśmy w stanie wykryć sytuacje niepoprawne, ale nasz kod może.
Paweł Starzyk Obiektowe metody projektowania systemów
PO13-1 / 19 Wykład 13 Wyjątki i ich zgłaszanie Wyłapywanie wyjątków Obsługa wyjątków Wykorzystanie polimorfizmu Filtrowanie wyjątków Błędy w konstruktorach.
Podstawy informatyki Funkcje Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi.
Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi i Pawła Jerzego Matuszyka Podstawy.
Podstawy informatyki Operatory rzutowania Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały.
Podstawy informatyki Mechanizm obsługi sytuacji wyjątkowych Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu.
STOS. STL (ang. Standard Template Library) jest to biblioteka zawierająca algorytmy, pojemniki, iteratory oraz inne konstrukcje w formie szablonów, gotowe.
K URS JĘZYKA C++ – WYKŁAD 3 ( ) Przenoszenie Składowe statyczne Funkcje wbudowane Argumenty domyślne.
InMoST, Java – przykładowa aplikacja Bartosz.Michalik
Programowanie Obiektowe – Wykład 6
Dzisiejsze zajęcia będą wyjątkowe…
Kurs języka C++ – wykład 3 ( )
Wątki, programowanie współbieżne
(według:
Programowanie Obiektowe – Wykład 2
Język C++ Typy Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi i Pawła Jerzego.
Zapis prezentacji:

Bezpieczeństwo wyjątków w C++: OpenGL Krzysztof Czaiński Opiekun pracy: dr inż. Cezary Stępień Krzysztof Czaiński

Motywacja Dużo literatury o OpenGL The Red Book (Addison-Wesley)‏ http://nehe.gamedev.net/ Dobrze opisane bezpieczeństwo wyjątków w C++ Exceptional C++, Herb Sutter OpenGL i wyjątki? GLT ( http://www.nigels.com/glt/ )‏ Building an OpenGL C++ Class, Dale Rogerson www.gaylesbiantimes.com/ Krzysztof Czaiński

Plan prezentacji Dlaczego wyjątki? Bezpieczeństwo wyjątków w C++ Inne sposoby traktowania błędów Bezpieczeństwo wyjątków w C++ Gdzie wstawić bloki try / catch, czy coś więcej? OpenGL, a wyjątki Więcej o bezpieczeństwie wyjątków Krzysztof Czaiński

Obsługa błędów, czyli problem komunikacji Autor klasy (biblioteki) może wykryć błąd, ale nie wie, co z nim zrobić Użytkownik klasy (biblioteki) wie, co zrobić z błędem, lecz nie potrafi go wykryć Przykłąd: Vector, odwołanie do nieistniejącego elementu. Krzysztof Czaiński Źródło: Materiały ZPR dr inż. Robert Nowaka

Sposoby traktowania błędów Wady Ignorowanie Zakończenie programu Komunikat dla użytkownika Kod powrotu Zmienna globalna Specjalny stan obiektu Rezerwacja zwracanej wartości Użytkownik może zignorować błąd Kod obsługi wymieszany z innym kodem Obiekt globalny – potencjalne źródło kłopotów Krzysztof Czaiński Źródło: Materiały ZPR dr inż. Robert Nowaka

Mechanizm wyjątków a zasoby void funkcja()‏ { A* a = NULL; try{a = new A; // Kod rzucający delete a; } catch ( ... )‏ { delete a; throw; } class A {/*...*/};   void funkcja()‏ { A* a = new A; // Kod rzucający delete a; } Niewygodne, nieczytelne, 2xnieefektywne Krzysztof Czaiński

Zdobywanie zasobów jest inicjalizacją (RAII)‏ Konstrukcja obiektu jest połączona ze zdobyciem zasobu Destrukcja obiektu jest połączona ze zwolnieniem zasobu Gdy obiekt jest lokalny, zasób jest zwalniany automatycznie w momencie niszczenia obiektu Krzysztof Czaiński

Sprytny wskaźnik template< typename X > class AutoPtr { public:   explicit AutoPtr( X* p = NULL ) : p_( p ) {} ~AutoPtr() { delete p_; } X& operator*() const { return *p_; } X* operator->() const { return p_; } private: X* p_; }; Możemy używać jak zwykłego wskaźnika. Uwaga: wszystkie metody throw()‏ Krzysztof Czaiński

Użycie sprytnego wskaźnika class A {/*...*/};   void funkcja()‏ { AutoPtr<A> a( new A ); // Kod rzucający a->metoda(); AutoPtr<A> b = a; // ??? } Co z kopiowaniem? Jak widać, bezpieczeństwo wyjątków jest czymś więcej, niż „gdzie wstawić bloki try/catch. Wręcz „jak unikać bloków try/catch”. Krzysztof Czaiński

Przykładowy kod z OpenGL void render()‏ { double v[3]; glBegin( GL_TRIANGLES ); for ( int i = 0 ; i < n ; ++i )‏ getVertex( i, v ); // rzuca? glVertex3dv( v ); } glEnd(); Krzysztof Czaiński

Automatyczny glBegin/glEnd #include <boost/utility.hpp> : boost::noncopyable struct Begin { explicit Begin( GLenum mode )‏ glBegin( mode ); } ~Begin()‏ glEnd(); }; Pytanie: jak zrobić niekopiowalność? Krzysztof Czaiński

Przykładowy kod z bezpiecznymi wyjątkami void render()‏ { double v[3]; Begin( GL_TRIANGLES ); for ( int i = 0 ; i < n ; ++i )‏ getVertex( i, v ); // rzuca? OK. glVertex3dv( v ); } uważać na Begin(); Krzysztof Czaiński

Przykładowy kod z bezpiecznymi wyjątkami (2)‏ void render()‏ { double v[3]; Begin begin( GL_TRIANGLES ); for ( int i = 0 ; i < n ; ++i )‏ getVertex( i, v ); // rzuca? OK. glVertex3dv( v ); } Krzysztof Czaiński

Zachowanie stanu OpenGL-a void select()‏ { glRenderMode( GL_SELECT ); // kod rzucający int hits = glRenderMode( GL_RENDER ); //... } Chcemy zagwarantować, żeby po wywołaniu select() OpenGL pozostał w trybie GL_RENDER Krzysztof Czaiński

Automatyczny glRenderMode class RenderMode : boost::noncopyable { public: RenderMode( GLenum mode, GLenum restoreMode )‏ : restoreMode_(restoreMode), restored_(false)‏ { glRenderMode( mode ); } ~RenderMode() { restoreRenderMode(); } GLint restoreRenderMode() { GLint result = 0; if ( ! restored_ ) { restored_ = true; result = glRenderMode( restoreMode_ ); } return result; private: GLenum restoreMode_; bool restored_; }; Krzysztof Czaiński

Zachowanie stanu OpenGL-a z auto- glRenderMode void select()‏ { RenderMode x( GL_SELECT, GL_RENDER ); // kod rzucający int hits = x.restoreRenderMode(); //... } Krzysztof Czaiński

Co to znaczy bezpieczeństwo wyjątków? Gwarancje bezpieczeństwa wyjątków wg Dave’a Abrahama: Podstawowa: Brak wycieku zasobów Wszystkie obiekty pozostają w stanie używalnym, ale nie koniecznie przewidywalnym Silna: Gdy wystąpi wyjątek, stan programu pozostaje niezmieniony Nothrow: Nigdy nie rzuca Czyli po prostu „there are no bugs” - Herb Sutter. Np. Container::AppendElements()‏ global commit-or-rollback semantics Niektóre funkcje muszą zapewniać, aby umożliwić powyższe gwarancje. Np. Destruktory, operacje dealokacji. Operacje auto_ptr są nothrow. Która w przypadku kodu z OpenGL? Krzysztof Czaiński Źródło: GotW #61

Korzyści Programowanie bezpieczne z uwzględnieniem wyjątków ma istotne zalety: Użytkownik klasy (biblioteki) może używać mechanizmu wyjątków Wyjątki nie zakłócą pracy programu W razie niespodziewanego błędu (np. braku pamięci) program może działać dalej Wszelkie zasoby zostają zwolnione mimo wyjątku Unikamy nie zwolnienia zasobów przez nieuwagę Zasoby są zwalniane automatycznie . Eclipse i OutOfMemoryException glBeginList i glEnd Krzysztof Czaiński

Bezpieczeństwo wyjątków a etap projektowania template < typename T > class Stack { public: T pop(); // ... private: T* tab_; size_t size_; }; template < typename T > void Stack<T>::pop( T& result )‏ { // assert( size_ > 0 ); result = tab_[size_-1]; --size_; } template < typename T > T Stack<T>::pop()‏ { // assert( size_ > 0 ); T result( tab_[size_-1] ); --size_; return result; } template < typename T > T Stack<T>::pop()‏ { // assert( size_ > 0 ); return tab_[--size_]; } Krzysztof Czaiński

Podsumowanie Warto pisać kod w C++ uwzględniając wyjątki i warto uwzględnić to już na etapie projektowania. Dla zainteresowanych polecam: ZPR, dr inż. Robert Nowak http://www.gotw.ca/gotw/ 1. Nie jak dokumentacja, dopisywana później. Krzysztof Czaiński