try catch

Vladislav1603
Offline
Зарегистрирован: 19.12.2015

При использовании блоков try catch вылазит вот такая ошибка: “error: exception handling disabled, use -fexceptions to enable”, куда нужно вводить этот – fexceptions чтобы все заработало?

    try{

    }catch(){   

    }

Код ошибки целиком:

time.ino: In function 'bool time_set(char*)':

time:18: error: expected type-specifier before ')' token

time:18: error: exception handling disabled, use -fexceptions to enable

expected type-specifier before ')' token

Datak
Offline
Зарегистрирован: 09.10.2014

По-моему, catch с пустыми скобками использовать нельзя. Нужно или указывать конкретный тип

1catch( int ErrCode ) { /* обработчик исключения типа int */ )

или писать многоточие, для обработки всего, что ещё не обработано

1catch( ... ) { /* обработчик всего остального */ )

-fexceptions, насколько я помню, добавляется в файле platform.txt.
Только версия IDE должна быть не слишком старой - в старых такого файла не было.

Но самое обидное то, что после успешной компиляции линкер всё равно выдаст ошибку - будет ругаться, что в файлах есть ссылки на функции, которые он не нашёл. В общем, не реализована в avr-gcc обработка исключений. Если кто-то в этом хорошо соображает - пожалуйста, можно дописать недостающие функции самостоятельно. :)

Вот, всё что знал. Может быть и ошибаюсь - давно этим не занимался, за это время могло что-то измениться. 

 

gregoryl
Offline
Зарегистрирован: 09.09.2013

Мне просто очень интересно зачем Вам в микроконтроллере try/catch ?

Вы собрались писать код который будет сам кидать и ловить исключения ?

Logik
Offline
Зарегистрирован: 05.08.2014

Datak пишет:

Если кто-то в этом хорошо соображает - пожалуйста, можно дописать недостающие функции самостоятельно. :)

Низя ни разу. Исключение - один из видов прерывания, только не от таймера или дерганья ноги, а от програмного события. Например попытка обратится по указателю за пределы памяти. Что делать - неизвестно, вот и вызывается прерывание, в нем должны разобратся с проблемой. И если процессор не поддерживает этот механизм и/или ОС не умеет обработать исключения - их не будет. На микроконтроллерах - не сильно и хотелось.

gregoryl
Offline
Зарегистрирован: 09.09.2013

Logik пишет:

Низя ни разу. Исключение - один из видов прерывания, только не от таймера или дерганья ноги, а от програмного события. Например попытка обратится по указателю за пределы памяти. Что делать - неизвестно, вот и вызывается прерывание, в нем должны разобратся с проблемой. И если процессор не поддерживает этот механизм и/или ОС не умеет обработать исключения - их не будет. На микроконтроллерах - не сильно и хотелось.

Вообще реально мимо, даже молоко не задели.... :-)

Исключения чистая фишка языка, и никакого отношения к прерываниям не имеет.

Более того Вы просто не реально удивитесь когда узнаете что SEGMENTATION FAULT, про который вы говорите, вообще не подлежит обработке через исключения если строго следовать стандартам, просто мелкомягкие нехило поработали что бы сделать для вас прослойку которая пытается решить эту проблему, причем это работает нормально далеко не всегда. Еще хуже дела обстоят с перехватом исключений типа OUT OF MEMORY ( вообще отдельная песня ). 

В линухе ( что бы он сдох не родившись ) надо обрабатывать сигналы для поимки всего подряд даже для деления ноль (если мне не изменяет память). И никто даже не пытается транслировать это в исключения.

Так что исключения это не обработка системных ошибок, это скорее механизм быстрого всплытия с глубины если с вашим кислородным балоном что-то случилось, именно с вашим балоном, а не тем что предоставила вам ОС/Железо.

Logik
Offline
Зарегистрирован: 05.08.2014

gregoryl пишет:

Исключения чистая фишка языка, и никакого отношения к прерываниям не имеет.

Более того Вы просто не реально удивитесь когда узнаете что SEGMENTATION FAULT, про который вы говорите, вообще не подлежит обработке через исключения если строго следовать стандартам, просто мелкомягкие нехило поработали что бы сделать для вас прослойку которая пытается решить эту проблему, причем это работает нормально далеко не всегда. Еще хуже дела обстоят с перехватом исключений типа OUT OF MEMORY ( вообще отдельная песня ). 

В линухе ( что бы он сдох не родившись ) надо обрабатывать сигналы для поимки всего подряд даже для деления ноль (если мне не изменяет память). И никто даже не пытается транслировать это в исключения.

Так что исключения это не обработка системных ошибок, это скорее механизм быстрого всплытия с глубины если с вашим кислородным балоном что-то случилось, именно с вашим балоном, а не тем что предоставила вам ОС/Железо.

А как "механизм быстрого всплытия с глубины" реализован, из всей глубины через 100500 уровней вложения подпрограмм?

Читать напимер здесь - http://kit.znu.edu.ua/eDoc/Arch/Pentium/orl24.html. И мелкомягкие там не причем, они только обернули это все в TRY... CATCH. А заложено как раз в железе, конкретно у Intela с 286 (правда криво), и вполне жизнеспособно в IAR-32 и позже.. Хотите SEGMENTATION FAULT - INT11. Те которые генерируются програмно - INTO и BOUND. 

Вот ещё здесь разжевано http://dims.karelia.ru/x86/intr.shtml

"Исключения являются для процессора внутренними событиями и сигнализируют о каких-либо ошибочных условиях при выполнении той или иной инструкции: деление на ноль, нарушение правил защиты, неприсутствие страницы и т.п.

Архитектура IA-32 предоставляет механизм обработки прерываний и исключений, прозрачный для прикладного и системного программного обеспечения. При возникновении прерывания или исключения текущая выполняемая задача автоматически приостанавливается на время выполнения обработчика, после чего ее выполнение возобновляется без потери непрерывности выполнения, кроме случаев, когда обработка прерывания или исключения вынуждает завершить программу."

Вашу точку зрения я встречаю не первый раз, на чем она основана, просто интересна причина массового заблуждения?

 

Datak
Offline
Зарегистрирован: 09.10.2014

Logik пишет:
Низя ни разу. Исключение - один из видов прерывания, только не от таймера или дерганья ноги, а от програмного события. Например попытка обратится по указателю за пределы памяти. Что делать - неизвестно, вот и вызывается прерывание, в нем должны разобратся с проблемой.

gregoryl пишет:
Вообще реально мимо, даже молоко не задели.... :-)

Исключения чистая фишка языка, и никакого отношения к прерываниям не имеет.

Более того Вы просто не реально удивитесь когда узнаете что SEGMENTATION FAULT, про который вы говорите, вообще не подлежит обработке через исключения

А вот и не подерётесь! :)

Оба правы, почти.

gregoryl чуть-чуть правее. Вот только насчёт SEGMENTATION FAULT... не знаю, по-моему как раз через исключения - как же ещё?

Logik тоже во всём прав, но он рассказывает совсем не про те исключения, о которых спрашивал ТС.

А ТС, как раз, хочет получить структурную обработку исключений... или структурированную что ли...
SEH, короче, по-иностранному. Кто её придумал - не помню, но кажется действительно майкрософтовцы.

К аппаратным особенностям процессора/контроллера она никакого отношения не имеет, и реализуется (или не реализуется) чисто программно, конкретным компилятором С/С++.

Logik пишет:
А как "механизм быстрого всплытия с глубины" реализован, из всей глубины через 100500 уровней вложения подпрограмм?

А никто и не говорит, что оно очень уж быстрое. Быстрое оно, скорее, для программиста - то есть, просто удобное, именно для всплытия через 100500 уровней.

Реализуется это именно как всплытие - т.е. не одним прыжком, а последовательно, через все уровни.
И заниматься составлением всех этих цепочек вызовов и исключений, а потом ещё и их "распутыванием", должны функции, которых в AVR-овской реализации нет, или пока нет.

Datak
Offline
Зарегистрирован: 09.10.2014

gregoryl пишет:
Мне просто очень интересно зачем Вам в микроконтроллере try/catch ?

Вы собрались писать код который будет сам кидать и ловить исключения ?

А что, иногда хочется! :)

Но в общем, да - тоже считаю, что каждому контроллеру свои задачи. Думаю, раз не реализовали - значит не очень то оно удобно на этих AVR8 реализуется. Может, места занимает неоправданно много.

Могу порекомендовать функции setjmp/longjmp. С ними можно делать что-то, вполне похожее на эти исключения, особенно если написать соответствующие макросы для try/catch/throw.

А если уж ещё дальше оффтопить... STM32 - и всё, нет больше этой проблемы.
Дороже всего на несколько центов - но компилятор там вполне серьёзный, и исключения присутствуют в полном объёме.

Только не подумайте, что агитирую за полный переход. Сам люблю эти AVR-ки, почему-то.
Но, ещё раз - иногда проще выбрать другой контроллер, чем лепить, например, какой-нибудь "Software UART".

Logik
Offline
Зарегистрирован: 05.08.2014

Datak пишет:

Logik пишет:
Низя ни разу. Исключение - один из видов прерывания, только не от таймера или дерганья ноги, а от програмного события. Например попытка обратится по указателю за пределы памяти. Что делать - неизвестно, вот и вызывается прерывание, в нем должны разобратся с проблемой.

gregoryl пишет:
Вообще реально мимо, даже молоко не задели.... :-)

Исключения чистая фишка языка, и никакого отношения к прерываниям не имеет.

Более того Вы просто не реально удивитесь когда узнаете что SEGMENTATION FAULT, про который вы говорите, вообще не подлежит обработке через исключения

А вот и не подерётесь! :)

Оба правы, почти.

gregoryl чуть-чуть правее. Вот только насчёт SEGMENTATION FAULT... не знаю, по-моему как раз через исключения - как же ещё?

Logik тоже во всём прав, но он рассказывает совсем не про те исключения, о которых спрашивал ТС.

А ТС, как раз, хочет получить структурную обработку исключений... или структурированную что ли...
SEH, короче, по-иностранному. Кто её придумал - не помню, но кажется действительно майкрософтовцы.

К аппаратным особенностям процессора/контроллера она никакого отношения не имеет, и реализуется (или не реализуется) чисто программно, конкретным компилятором С/С++.

Logik пишет:
А как "механизм быстрого всплытия с глубины" реализован, из всей глубины через 100500 уровней вложения подпрограмм?

А никто и не говорит, что оно очень уж быстрое. Быстрое оно, скорее, для программиста - то есть, просто удобное, именно для всплытия через 100500 уровней.

Реализуется это именно как всплытие - т.е. не одним прыжком, а последовательно, через все уровни.
И заниматься составлением всех этих цепочек вызовов и исключений, а потом ещё и их "распутыванием", должны функции, которых в AVR-овской реализации нет, или пока нет.

О ещё представитель сообщества свидетелей исключений без аппаратной поддержки!

Я для кого писал в первом сообщении в теме о необходимости кроме аппаратной поддержки еще и поддержки в ОС? Вот это и есть (structured exception handling, SEH) но его наличие по барабану без аппаратного механизма прерывания. Читайте например здесь http://www.e-reading.club/chapter.php/89563/92/Russinovich,_Solomon_-_1.Vnutrennee_ustroiistvo_Windows_(gl._1-4).html

там и про векторы прерываний, и про структурную обработку. Для ленивых - цитата "Учтите: хотя обработка исключений возможна через расширения языка программирования (например, с помощью конструкции_try в Microsoft Visual C++), она является системным механизмом и поэтому не зависит от конкретного языка.

B системах типа x86 все исключения имеют предопределенные номера прерываний, прямо соответствующие записям в IDT, ссылающимся на обработчики ловушек конкретных исключений."

Поймите правильно, я знаю как это работает. В отличии от Вас. Убедить меня голыми словами не получится. Какие ещё не те исключения?!

И в данном вопросе меня интересует только один момент - источник стойкого убеждения что "К аппаратным особенностям процессора/контроллера она никакого отношения не имеет, и реализуется (или не реализуется) чисто программно, конкретным компилятором С/С++." Откуда Вы это взяли вообще?

Если Вы и далее в этом уверены, то раскажите что происходит в системе непосредственно при исполнении машинной команды обратившейся за пределы доступного сегмента.  например в программе идут подряд команды and [bx+6F],dh и jb 0087,  первая обращается за пределы. Далее что?.

ПС. Быстро раскручиваются исключения или нет - "мопед не мой", слово "быстро" из цитаты. 

ППС. В более навороченных чем наны и микры ардуиновских контроллерах аппаратная поддержка присутствует, тех же STMах. И соответственно обработка исключений есть, на том же компиляторе gcc.

Datak
Offline
Зарегистрирован: 09.10.2014

Logik пишет:
Вот это и есть (structured exception handling, SEH)

Каюсь, каюсь, каюсь, каюсь. :)

SEH я сюда приплёл совсем не по делу. Запутался в терминологии.

Logik пишет:
Какие ещё не те исключения?!

Вот такие: Операторы try, throw и catch (C++)

ТС ведь спрашивал о них - ключ -fexceptions относится только к ним, и ни к чему другому.

И к аппаратным исключениям они отношения не имеют.

Logik
Offline
Зарегистрирован: 05.08.2014

Datak пишет:

Вот такие: Операторы try, throw и catch (C++)

И к аппаратным исключениям они отношения не имеют.

1. С чего Вы это взяли?

2. Что происходит в системе непосредственно при исполнении машинной команды обратившейся за пределы доступного сегмента.  например в программе идут подряд команды and [bx+6F],dh и jb 0087,  первая обращается за пределы сегмента. Далее что? как происходит передача управления на команды блока catch?.

ПС. Для остальных читателей форума всеже напомню, что SEH имеет непосредственное отношение к процессу, на платформе Windows  эта технология обеспечивает поддержку исключений на уровне ОС в виде, позволяющем встроить код блока try в обработку исключения. Именно об этом по ссылке  из моего предыдущего поста, но кто ж их читает )))

Datak
Offline
Зарегистрирован: 09.10.2014

Logik пишет:
2. Что происходит в системе непосредственно при исполнении машинной команды обратившейся за пределы доступного сегмента.  например в программе идут подряд команды and [bx+6F],dh и jb 0087,  первая обращается за пределы сегмента. Далее что? как происходит передача управления на команды блока catch?.

Logik, я не опишу в подробностях, что там происходит, тем более для интеловского процессора, который последний раз близко видел очень давно. Но общий смысл происходящего при прерываниях и исключениях я представляю, поверьте.

В любом случае, при исключении процессор сохраняет определённый контекст в специальных предназначенных для этого регистрах - скажем, адрес и код исключения, ну и ещё какую-то информацию о своём состоянии. Допустим, текущий уровень привилегий, если для данного процессора есть такое понятие.

Потом, в зависимости от кода (типа) исключения, опять же по указателям в определённых регистрах и таблицах, происходит "загрузка" нового контекста - т.е. осуществляется переход, собственно, на обработчик исключения. Тоже уже с другими привилегиями, и другим набором доступных сегментов памяти, если говорить о любимых x86.

Дальше всё зависит от того, как реализован сам этот обработчик исключений. Тут уж я скромно умолкаю, поскольку не эксперт и не претендую.

Напишу только - возврат из обработчика происходит в обратном порядке. Хотя, это совсем не обязательно - всё зависит от идей, задумок и талантов программиста.

Вот, так получилось. Длинно, но пришлось - чтобы не игнорировать Ваш вопрос,  к тому же повторно. :)

Только объясните мне, зачем я всё это писал? Я же не отрицал наличие механизма исключений, и возможности его аппаратной поддержки процессором.

Но я говорил и говорю, что это совсем другой механизм - не тот, о котором спрашивал ТС.

Они, эти механизмы, могут использоваться одновременно - тоже не спорю. Но могут и абсолютно независимо, потому что это совершенно разные вещи. Я не прав?

Logik
Offline
Зарегистрирован: 05.08.2014

Datak пишет:

В любом случае, при исключении процессор сохраняет определённый контекст в специальных предназначенных для этого регистрах - скажем, адрес и код исключения, ну и ещё какую-то информацию о своём состоянии. Допустим, текущий уровень привилегий, если для данного процессора есть такое понятие.

Потом, в зависимости от кода (типа) исключения, опять же по указателям в определённых регистрах и таблицах, происходит "загрузка" нового контекста - т.е. осуществляется переход, собственно, на обработчик исключения. 

Вот. По аппаратным исключениям, в общих чертах понимаете, что происходит. При програмнных происходит практически тоже самое но:

1. Причина исключение не проблема при выполнении команды, а непосредственно команда INT...

2. Контекст сохраняется чисто програмным путем (а в обоих случаях сохраняется на стеке) 

3. Все это для Вас выглядит как throw и спрятано в соответствующую длл.

А дальше как и при любом прерывании\исключении, не зависимо от природы его - переход на соответствующий вкетор, смена уровня привеле, сохранение контекста.... и гдето там ближе к концу, возможно раскрутка стека.

 

Datak пишет:

Дальше всё зависит от того, как реализован сам этот обработчик исключений. Тут уж я скромно умолкаю, поскольку не эксперт и не претендую.

Не, не не!! Не останавливаемся! Здесь как раз и начинается самое интересное. Смотрим винду.

Диспетчеризация исключений.

Как видим центровой здесь диспетчер исключений, замечаем - он один, нет ни аппаратных ни програмных исключений отдельно!. Он начина пытатся обработать исключения разными методами. Нас интересует SEH-фрейм. Именно там зарегестрированы наши catch. Вот по сути круг и замкнулся.

Datak пишет:

Напишу только - возврат из обработчика происходит в обратном порядке. Хотя, это совсем не обязательно - всё зависит от идей, задумок и талантов программиста.

Тут варианты, много но важны некоторые:

1. С чего начинали. Исключение отсутствия страницы. Один из возможных вариантов - выгружена страница в файл подкачки. Страница загружается. Вот откуда свопинг стартует!! После этого команда вызвавшая исключение перезапускается и работа продолжается.

2. Исключение прикладное, придуманное программистом, т.к. система его не знает, то обязательно прийдем в свой catch

3. Обработать исключение не хочет ни кто, процесс завершается аварийно.

Datak пишет:

Но я говорил и говорю, что это совсем другой механизм - не тот, о котором спрашивал ТС.

Они, эти механизмы, могут использоваться одновременно - тоже не спорю. Но могут и абсолютно независимо, потому что это совершенно разные вещи. Я не прав?

Как видите никакого другого механизма в природе не существует. Исключения обрабатываются не зависимо от их источника как особый вид прерываний, соответственно нужна аппаратная поддержка. 

В линуксе все выглядит несколько по иному, но суть не меняется на сколько я знаю.

Вопрос вобще имеет достаточно конкретное воплощение. Как писал выше, значительное количество программистов не понимают ресурсоемкость обработки исключений и что стоит за try...catch  и лепят их где надо и ненадо.  Логику на них строят, место предпроверки используют что вызывает в итоге тормозню, как Вы замечали выше. Кстати если бы исключения реализовывались чисто средствами языка, и всего этого не требовалось  (переключение в режим ядра да поиск обработчика исключений только чего "весят") то все бы летало. 

Только я так и не понял откуда пошел миф о 2-x разных механизмах исключенй называемых одним и тем же словом. По Вашей ссылке на msdn не описывается механизм работы try...catch, дальше скромного упоминания SEH на соседней странице там не идут.