В этом варианте при возникновение исключения вызывается деструктор статического класса, но если я убираю строку "cout <<"XZ\n"<<endl;" (в ф-ии f1() ), то вызова этого деструктора не вижу.
Здравствуйте Аноним, Вы писали:
А>В этом варианте при возникновение исключения вызывается деструктор статического класса, но если я убираю строку "cout <<"XZ\n"<<endl;" (в ф-ии f1() ), то вызова этого деструктора не вижу.
Насколько я понимаю работу исключений в VC6, это связано с тем, что если компилятор не видит генерации C++-исключений, то он и не создает код, который отвечает за размотку стека при исключениях.
Когда ты добавляешь вызов cout << "XZ", то компилятор видит, что в данном блоке может возникнуть C++-исключение, поэтому надо сгенерировать код "размотки".
P.S. Деление на ноль — это не C++-исключение, это "машинное" исключение, которое для программы и компилятора является полной неожиданностью в run-time, а на этапе компиляции его не видно.
Здравствуйте Аноним, Вы писали:
А>В этом варианте при возникновение исключения вызывается деструктор статического класса, но если я убираю строку "cout <<"XZ\n"<<endl;" (в ф-ии f1() ), то вызова этого деструктора не вижу. А>
Насколько я понимаю, деление на ноль вызывает исключение, обработка которого ложится на плечи операционой системы и не имеет к исключениям С++ никакого отношения. Под FreeBSD данный пример приводит к тому, система шлет сигнал SIGFPE (Floating point exception) и валит прогу в core.
Здравствуйте santucco, Вы писали:
S>Насколько я понимаю, деление на ноль вызывает исключение, обработка которого ложится на плечи операционой системы и не имеет к исключениям С++ никакого отношения. Под FreeBSD данный пример приводит к тому, система шлет сигнал SIGFPE (Floating point exception) и валит прогу в core.
Под VC try/catch имеет возможность поймать системное исключение.
В данном случае вся проблема в том, что из-за "оптимизации" VC не генерируется код размотки стека, если не видит выброса C++-исключений
Здравствуйте DarkGray, Вы писали:
DG>Здравствуйте santucco, Вы писали:
S>>Насколько я понимаю, деление на ноль вызывает исключение, обработка которого ложится на плечи операционой системы и не имеет к исключениям С++ никакого отношения. Под FreeBSD данный пример приводит к тому, система шлет сигнал SIGFPE (Floating point exception) и валит прогу в core.
DG>Под VC try/catch имеет возможность поймать системное исключение. DG>В данном случае вся проблема в том, что из-за "оптимизации" VC не генерируется код размотки стека, если не видит выброса C++-исключений
"Мы в Microsoft считаем, что стандарт всегда можно улучшить" (Дейл Роджерсон, если не ошибаюсь)
Здравствуйте santucco, Вы писали:
S>>>Насколько я понимаю, деление на ноль вызывает исключение, обработка которого ложится на плечи операционой системы и не имеет к исключениям С++ никакого отношения. Под FreeBSD данный пример приводит к тому, система шлет сигнал SIGFPE (Floating point exception) и валит прогу в core.
DG>>Под VC try/catch имеет возможность поймать системное исключение. DG>>В данном случае вся проблема в том, что из-за "оптимизации" VC не генерируется код размотки стека, если не видит выброса C++-исключений S>"Мы в Microsoft считаем, что стандарт всегда можно улучшить" (Дейл Роджерсон, если не ошибаюсь)
Все-таки это лучше, чем core dumped из-за простого деления на ноль
Re[5]: Исключения(exception) и вызов деструкторов
От:
Аноним
Дата:
01.08.02 13:37
Оценка:
Здравствуйте DarkGray, >Насколько я понимаю работу исключений в VC6, это связано с тем, что если компилятор не видит >генерации C++-исключений, то он и не создает код, который отвечает за размотку стека при исключениях.
Пожалуй в этом что-то есть.
Когда я между
Ctest Ct2(2); и делением на 0х0 вставляю вызов f2() описанной: void f2(){}
Вызов деструктора появляется
Здравствуйте DarkGray, Вы писали:
DG>Здравствуйте santucco, Вы писали:
S>>>>Насколько я понимаю, деление на ноль вызывает исключение, обработка которого ложится на плечи операционой системы и не имеет к исключениям С++ никакого отношения. Под FreeBSD данный пример приводит к тому, система шлет сигнал SIGFPE (Floating point exception) и валит прогу в core.
DG>>>Под VC try/catch имеет возможность поймать системное исключение. DG>>>В данном случае вся проблема в том, что из-за "оптимизации" VC не генерируется код размотки стека, если не видит выброса C++-исключений S>>"Мы в Microsoft считаем, что стандарт всегда можно улучшить" (Дейл Роджерсон, если не ошибаюсь)
DG>Все-таки это лучше, чем core dumped из-за простого деления на ноль
Ну если серьезно, то я бы не сказал что лучше, потому что "простое деление на ноль" на самом деле довольно серьезная ошибка программиста.
Впрочем, мне не хотелось бы затевать новый "религиозный" флейм.
И если народ привык полагаться на компилятор в подобных случаях — то регистр флагов ему в руки
Здравствуйте santucco, Вы писали:
DG>>Все-таки это лучше, чем core dumped из-за простого деления на ноль S>Ну если серьезно, то я бы не сказал что лучше, потому что "простое деление на ноль" на самом деле довольно серьезная ошибка программиста.
Вот только пользователи это слышать нихотят, а начинают при очередном падении топать ногами и вспоминать Билл Гейтса.
S>И если народ привык полагаться на компилятор в подобных случаях — то регистр флагов ему в руки
Дык, все ошибки не исправишь, а так хоть все остальное будет работать.
Здравствуйте Аноним, Вы писали:
А>В этом варианте при возникновение исключения вызывается деструктор статического класса, но если я убираю строку "cout <<"XZ\n"<<endl;" (в ф-ии f1() ), то вызова этого деструктора не вижу. А>
Если есть желание чтобы компилятор правильно ловил такие исключения как деление на ноль в С++ try/catch блоках, то для MS Visual C++ нужно включить поддержку для асинхронных исключений, при этом код заметно распухнет и будет медленнее, но будет все правильно ловить и вызывать деструкторы, по умолчанию она выключена. По Стандарту все исключения синхронные, так что поддержка асинхронных исключений это расширение Стандарт MS'ом.
Здравствуйте dupamid, Вы писали:
D>По Стандарту все исключения синхронные, так что поддержка асинхронных исключений это расширение Стандарт MS'ом.
Маленькое буквоедство: стандарт не различает синхронные и асинхронные исключения, просто говорит, что деление на ноль, в частности, вызывает неопределенное поведение. Что делать в ответ на неопределенное поведение — дело разработчиков компилятора.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте Павел Кузнецов, Вы писали:
ПК>Маленькое буквоедство: стандарт не различает синхронные и асинхронные исключения, просто говорит, что деление на ноль, в частности, вызывает неопределенное поведение. Что делать в ответ на неопределенное поведение — дело разработчиков компилятора.
По Стандарту исключения синхронные — в том смысле, что они происходят по запросу из программы в явном виде посредством throw и никак иначе, следовательно, если компилятор в коде не видит throw или чего-то еще, что может привести к выбросу исключения, как-то вызов функции без спецификатора throw(), то он считает, что исключение выброшено быть не может и следовательно генерировать код, для его поимки, неэффективно и он его не генерирует. Никаких других исключений в Стандарте С++ нет, другое дело сигналы, они асинхронны. Понятия синхронных и асинхронных исключений, с которыми я оперировал, взяты не из Стандарта, а из описания MS, но они достаточно наглядны и позволяют разобраться, в чем здесь дело и как с этим бороться.
Кстати, правильная работа приводимого примера обеспечивается как раз из-за вызова функции вывода в поток, так как компилятор не знает, выбрасывает ли она исключения, он считает, что она их выбрасывает и генерирует соответствующий код для их поимки.
Здравствуйте dupamid, Вы правы:
Ответ оказался прост. Нашел у Джон Роббинс "Отладка приложений в Windows"
В VC++ у компилятора есть два ключа: /EHa (/EHac) и /EHs (/EHsc , /GX)
В VC++ 5.0 поумолчанию — /EHa — как все и считали
В VC++ 6.0 поумолчанию (см. /GX) — /EHs — обработка исключений/раскрутка стека создается только если:
время жизни локального обьекта Ctest Ct2(2); пересекается с
а)вызовом ф-ии
б)throw
поэтому
f1(){
int *pi=new int;//-бесполезно, не пересекается со временем жизни Ct2 (деструктора не будет)
Ctest Ct2(2);
//exception
int *pi=new int;}//-будет деструктор
}
Но вот вопрос, а почему
cout <<"XZ\n"<<endl; — вызов ф-ии
printf("end f1\n"); — а это с точки зрения компилятора уже не вызов ф-ии ????
Здравствуйте BK, Вы писали:
BK>Но вот вопрос, а почему BK>cout <<"XZ\n"<<endl; — вызов ф-ии BK>printf("end f1\n"); — а это с точки зрения компилятора уже не вызов ф-ии ????
Вызов, но функции extern "C", которые не должны выбрасывать исключения, хотя на самом деле могут и от этого может быть множестов проблем.
Здравствуйте DarkGray, Вы писали:
DG>Здравствуйте Аноним, Вы писали:
А>>В этом варианте при возникновение исключения вызывается деструктор статического класса, но если я убираю строку "cout <<"XZ\n"<<endl;" (в ф-ии f1() ), то вызова этого деструктора не вижу.
DG>Насколько я понимаю работу исключений в VC6, это связано с тем, что если компилятор не видит генерации C++-исключений, то он и не создает код, который отвечает за размотку стека при исключениях.
DG>Когда ты добавляешь вызов cout << "XZ", то компилятор видит, что в данном блоке может возникнуть C++-исключение, поэтому надо сгенерировать код "размотки".
DG>P.S. Деление на ноль — это не C++-исключение, это "машинное" исключение, которое для программы и компилятора является полной неожиданностью в run-time, а на этапе компиляции его не видно.
на сколько я помню это называется синхронной обработкой исключений при асинхронной все иначе.
регулируется это дело опциями /Eh
Здравствуйте dupamid, Вы писали:
ПК>>Маленькое буквоедство: стандарт не различает синхронные и асинхронные исключения, просто говорит, что деление на ноль, в частности, вызывает неопределенное поведение. Что делать в ответ на неопределенное поведение — дело разработчиков компилятора.
D>По Стандарту исключения синхронные — в том смысле, что они происходят по запросу из программы в явном виде посредством throw и никак иначе,
Не обязательно. В случае undefined behavior разработчики компилятора имеют право определить поведение программы, как им заблагорассудится, в т.ч. и бросить исключение. Это я к тому, что возбуждение исключения в случае деления на ноль расширением не является, а является одним из вариантов неопределенного поведения.
D>Понятия синхронных и асинхронных исключений, с которыми я оперировал, взяты не из Стандарта, а из описания MS, но они достаточно наглядны и позволяют разобраться, в чем здесь дело и как с этим бороться (...)
Дык, по существу-то я ничего и не возражал. Просто, сканируя этот тред на случай, что кто-то правильный ответ уже дал, нашел твой, с которым согласен, за исключением формулировки, касающейся расширения :-)
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен