wiki:plans_for_lect2
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) {

        }
Last modified 8 years ago Last modified on 02/29/16 21:47:16