Qraizer

Advanced Member | Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору ALeXstrange, вот на SEH, если поможет: Код: float power(int t, int k) { int tempk = std::abs(k); int tempt = t; while(tempk-- > 1) { t = t * tempt; } if(k > 1) return t; else { __try { t = 1 / t; } __except(GetExceptionCode() == EXCEPTION_INT_DIVIDE_BY_ZERO ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { std::cerr << "Delenie na 0"; } return t; } } | Только функция всё равно неверная. Деление должно быть не целочисленным, а с плавающей точкой, иначе значения для отрицательных порядвок будут всегда нулевыми: Код: float power(int t, int k) { int tempk = std::abs(k); int tempt = t; float res; while(tempk-- > 1) { t = t * tempt; } if(k > 1) return t; else { __try { res = 1.0f / t; } __except(GetExceptionCode() == EXCEPTION_FLT_DIVIDE_BY_ZERO ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { std::cerr << "Delenie na 0"; _clearfp(); } return res; } } | И ещё в main() надо добавить Код: _controlfp(~_EM_ZERODIVIDE, _MCW_EM); | чтобы размаскировать исключение деления на ноль с плавающей точкой. Цитата: Жаль, что стандартная библиотека С++ не предоставляет такой возможности как выявление возникновения данной исключительной ситуации в процессе ее появления. | Язык C++ не привязан к конкретной платформе. В отличие от C#, C++/CLI, Managed C итп. Он спроектирован для поддержки любого железа, включая даже микроконтроллеры. Естественно, если разработчик этого железа не поленится реализовать компилятор для него. Стандартная библиотека в подобных условиях не может идти на поводу некоторых платформ в угоду другим, даже если первых гораздо больше. Аппаратные исключения очень платформозависимы. Где-то они есть, где-то нет, где-то их столько, где-то столько, где-то список их таков, где-то вот таков итд итп ипр. Стандарт языка в угоду себе не имеет права требовать от любого железа однакового поведения. Поэтому он никак их не специфицирует и не требует, чтобы они так или иначе отображались на исключения C++. Конкретно по твоему случаю. Аппаратные исключения под Win32 отображаются на SEH, каковая предоставляется операционной системой, а не языком. Поэтому использовать SEH может программа, написанная на чём угодно. Т.к. SEH сильно зависима от платформы - а Win32 реализована на платформах в количестве гораздо больше одной Intel x86 - то использование SEH подразумевает тесное взаимодействие с железом. Т.к. такое тесное взаимодействие противоречит принципам самого Win32, то поддержка SEH большей частью должна обеспечиваться компилятором и CRT, точнее их расширениями Стандарта языка. В MS VC это __try/__except/__finally/__leave итп. Теоретически подобный механизм должен поддерживать любой компилятор любого языка программирования, портированный под Win32, потому что это требование Win32. Что касается других операционных систем, то там могут быть совсем другие механизмы обработки аппаратных исключений. В POSIX, например, это сигналы. Так что выбирай. Хочешь переносимо писать на Плюсах, используй средства Стандарта языка и мирись с некоторыми недостатками. Поверь, преимущества перевешивают с лихвой. Хочешь под Win32 - смело используй документрованные средства ОС. Но только документированные, ибо недокументированные могут меняться без предупреждения в любом сервис-паке и даже самом крохотном фикс-обновлении, а потом горе-авторы мучаются поддержкой десятков вариантов своего "шедевра". Хочешь и то, и другое, ... обычно это делается собственной библиотекой, которая реализована по-разному на разных платформах, но имеет одинаковый интерфейс во всех своих реализациях. Тогда использование её будет переносимым, а добавление новых реализаций для новых платформ или модификация имеющихся для уже реализованных не будут затрагивать уже написанный и отлаженный переносимый код. ИМХО самый правильный вариант.
---------- Одни с годами умнеют, другие становятся старше. |
| Всего записей: 613 | Зарегистр. 08-08-2006 | Отправлено: 15:35 03-04-2010 | Исправлено: Qraizer, 15:41 03-04-2010 |
|