{{{ 1. Виды ошибок в runtime - ошибки по вине программиста int a[10]; for(int i = 0; i <= 10; i++) { a[i] = i; } char s; strlen(s); - ошибки по вине окружения пользователь ввел неправильные данные на диске закончилось место разорвалось сетевое соединение 2. Ошибки по вине программиста - выявить ошибки на стадии отладкиж assert(s != NULL), gcc -DNDEBUG автотесты (google test) 3. Ошибки по вине окружения - предусмотреть обработку ошибок вывод сообщения об ошибке освободить ресурсы (динамическая память, открытые файлы, ...) поптыка восстановления (например, использование параметров по умолчанию вместо данных некорректного конфига) 4. С style FILE* fin = fopen("a.txt", "r"); //одно из возвращаемых значений зарезервировано if( fin == NULL ) { // возможные причины: нет файла; нет прав; ... printf("s\n", strerror(errno)); //errno --- глобальная переменная (код последней ошибки) } Недостатки: - не всегда возможно зарезервировать значение под ошибку: atoi("0") == atoi("abbc") - недостаточно информации об ошибки: код, текстовое сообщение, имя функции и т.д. - перемещана логика работы и логика обработки ошибки int res1 = robot.up(); if( res1 < 0 ){ //обработка } else { int res2 = robot.down(); if( res2 < 0) { //обработка } } 5. C++ style - try/catch/throw View::initModel --> Model::init --> Config::load void Config::load(...) { if (ошибка формата) { throw FileException("Bad config format"); //бросить можно значение любого типа } } void Model:init(...) { try { // блок логики работы Config c; c.load(this); initMonsters(); initHeroes(); } catch(FileException& e) { // блок обработки ошибок setDefaultValues(); // здесь нельзя вывести сообщение об ошибке, т.к. неизвестно, // какой тип View текстовый или графический => передать ошибку дальше throw e; } } void View::initModel(...) { try { model.init(); createStartScreen(); } catch(FileException& e) { showMessageBox(e.message()); } } 6. Детали - поймать и пробросить ошибку любого типа try { doSomething() } catch(...) { throw; } - stack unwinding f() { try { g(); } catch(MyException& e) { } } g() { h(); } h() { throw MyException(); } - сработает первый подходящий catch (порядок важен) class BaseException { }; class DerivedException : public class BaseException { }; try { } catch(DerivedException& de) { } cacth(BaseException& be) { } }}}