Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1] 2  Все   Вниз
  Печать  
Автор Тема: Обработка исключений на языке C  (Прочитано 93403 раз)
0 Пользователей и 9 Гостей смотрят эту тему.
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« : 02-02-2011 09:15 » 

Обсуждение статьи: «Обработка исключений на языке C»

* TriangleArea.zip (8.69 Кб - загружено 1444 раз.)
« Последнее редактирование: 27-07-2011 19:15 от RXL » Записан

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

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 02-02-2011 12:33 » 

Статья готова.

Обсуждаем, публикуем.
Записан

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

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 02-02-2011 13:16 » 

Интересная статья. Не видел до этого ни одного логичного применения longjmp.

Добавлено через 1 день, 4 часа, 38 минут и 17 секунд:
Интересно, каковы лимиты вложенности блоков таких try-catch?
« Последнее редактирование: 03-02-2011 18:12 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 03-02-2011 18:38 » 

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

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #4 : 03-02-2011 19:25 » 

Интересно, каковы лимиты вложенности блоков таких try-catch?

Документацией не лимитируется. Похоже, в разумных пределах вложенность не ограничена.

Добавлено через 4 минуты и 36 секунд:
Если я правильно понял, предложенное решение ловит только те исключительные ситуации, порождение которых прописано программистом. В случаях же ошибок типа деления на ноль данный механизм не сработает.

Конечно. Штатного-то механизма обработки исключений в C нет, здесь приведена лишь его довольно искусная имитация при помощи longjmp и макросов. Поэтому перехватывать ошибки runtime при помощи CException не получится, равно как и ошибки подпрограмм стандартной библиотеки. Ну и, само собой, не удастся выбрасывать ничего более информативного, чем беззнаковое целое.
« Последнее редактирование: 03-02-2011 19:30 от Dale » Записан

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

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 04-02-2011 07:28 » 

Если ориентироваться именно на микроконтроллеры, то не помню, чтобы там было деление (с системой команд AVR знаком давно, поверхностно и все уже забыл, а в 8051 и PIC деления нет как класса, в AD21xx исключения не полагалось, а с другими м/к не сталкивался). Исходя из этого предположу, что нужно внедрить в код функции деления соотв. Throw.
При отсутствии защиты памяти (обычное дело в м/к и мобильных процессорах) других ошибок не будет.
Не забываем, что ресурсов мало - тут не винда с дровами от неведомого индусского производителя. Т.е. код максимально контролируется разработчиком.
Вывод: предложенный в статье механизм покрывает все потребности в обработке исключений.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #6 : 04-02-2011 07:32 » 

Цитата
а в 8051 и ... деления нет как класса,
ай-ай-ай Улыбаюсь Верни слова взад.

Команда "div AB" выполняет деление содержимого аккумулятора на содержимое регистра "B". Частное помещается в А, остаток - в В
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 04-02-2011 07:41 » 

Что-то с sourceforge? У меня не получается посмотреть исходники на сайте проекта - при попытке открыть ветку исходников страничка сваливается куда-то налево и ничего не кажет. Было любопытно посмотреть, как реализованы макросы. В статье на это, к сожалению особых намёков нет, а это ведь самое интересное Улыбаюсь

Честно говоря, longjmp никогда не пользовался - как-то в голову не приходило даже, совмещать C и обработку исключений: в моём представлении, код на C должен быть или дубово надёжным, или не быть Улыбаюсь Правда, я на C по-крупному только видеокодек и обвязку к нему пилил, там ничего такого и не требовалось.
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #8 : 04-02-2011 07:44 » 

Каюсь, Слав. 13 лет прошло. Да и не использовал я эту команду. Сейчас вспомнил - 4 машинных цикла выполнялась.

Добавлено через 2 минуты и 22 секунды:
Вад, прикрепил к посту.

* cexception_1_2.zip (418.06 Кб - загружено 683 раз.)
« Последнее редактирование: 04-02-2011 07:47 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #9 : 04-02-2011 08:02 » 

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

Обработка исключений для того и введена, чтобы гарантированно реагировать на ошибочные ситуации. Наоборот, именно еe отсутствие очень затрудняет написание надежного кода на C (или же делает его чрезмерно громоздким, что и продемонстрировано в статье).

Было любопытно посмотреть, как реализованы макросы. В статье на это, к сожалению особых намёков нет, а это ведь самое интересное Улыбаюсь
Вад, прикрепил к посту.

К статье приложен рабочий демо-проект, там включено все необходимое, включая исходники CException.
Записан

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

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #10 : 04-02-2011 10:19 » 

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

Обработка исключений для того и введена, чтобы гарантированно реагировать на ошибочные ситуации. Наоборот, именно еe отсутствие очень затрудняет написание надежного кода на C (или же делает его чрезмерно громоздким, что и продемонстрировано в статье).
Считаю последнюю фразу преувеличением Улыбаюсь В статье приведён не слишком удачный пример, когда проводится много проверок (к тому же, будто бы не к месту), которые к тому же непонятны -- в том смысле, что код элементарно плохо читается из-за всех этих проверок.  Почему a <= fabs(b-c), а не c <= fabs(a - b)?
Записан
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #11 : 04-02-2011 11:29 » 

Почему a <= fabs(b-c), а не c <= fabs(a - b)?

Не любые три отрезка могут образовать треугольник. Если взять два отрезка произвольной длины, то третий должен быть не больше их суммы и одновременно не меньше разности. Если угодно, можно взять условие c <= fabs(a - b), но тогда одновременно нужно проверить c >= a + b. Я просто не стал загромождать статью такими элементарными вещами, поскольку тема все-таки исключения в C, а не введение в геометрию.
Записан

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

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #12 : 04-02-2011 12:07 » 

Я просто не стал загромождать статью такими элементарными вещами, поскольку тема все-таки исключения в C, а не введение в геометрию.
Я это понимаю. В том и дело, что все проверки, без комментариев, выглядят не очень читаемо, скажем так. Не считываются как семантическая единица, что ли.

Вот если вынести всё в предикат isValidTriangle -- то я бы сразу понял: вот, тут мы проверяем, правильные ли нам стороны подсунули, может ли это быть треугольником. Но когда есть такая проверка - вроде бы, нет нужды уже городить что-то насчёт проверки площади - просто возвращать -1 и задокументировать и в errno записать ошибку INVALID_ARG, раз нам такие плохие данные дают. А то и вовсе считать то, что дают, а предикат пусть клиент сам проверяет.
Записан
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #13 : 04-02-2011 12:40 » 

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

Добавлено через 14 минут и 40 секунд:
Вот простой пример.

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

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

А вот это:
А то и вовсе считать то, что дают, а предикат пусть клиент сам проверяет.
плохо вяжется с
в моём представлении, код на C должен быть или дубово надёжным, или не быть Улыбаюсь

Это скорее подход в стиле: "сами нарвались, так получите же по полной".
« Последнее редактирование: 04-02-2011 12:56 от Dale » Записан

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

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #14 : 04-02-2011 14:36 » 

Пример неудачный. Если есть корректная призма - для чего проверять корректность треугольного основания? А если нет - чего ради нам считать площадь этого основания, если призма уже некорректная?

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

Если вы видели java-код с развесистым набором catch-ей, то не понимаю, как можно находить этот подход "лучше" и "красивее", чем обработка errno и возвращаемых значений. Исключения нужно очень рано перехватывать, иначе что число вариантов исключений, что число возможных некорректных поведений программы, будет расти, и неважно, чего будет много: веток с проверкой, какой код ошибки в errno, или веток catch, проверяющих, какое, всё-таки, исключение из возможных 5 было сгенерировано.

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

ru
Offline Offline
Пол: Мужской

« Ответ #15 : 04-02-2011 16:27 » 

Это, конечно, вопрос вкуса. Но лично мне нравится раздельно описывать основной и альтернативные сценарии какой-то деятельности. Единственно, что при помощи данного механизма, который требует написания if и вызова throw, делать такое разделение не очень удобно. Если только каждую проблемную функцию оборачивать в другую функцию, которая делает нужные проверки и генерирует соответствующие исключения. Однако, количества кода это не сокращает.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #16 : 04-02-2011 17:55 » new

Ещё один минус - работа с памятью. Поскольку C - язык не так чтоб совсем объектный, подчищать динамически выделенные ресурсы после throw будет просто некому, и в таких случаях будут течи. Или будет неаппетитная очистка всех ресурсов перед каждым throw, что несколько испортит раздельные сценарии для Димки.

Теоретически, сюда можно прикрутить какой-нибудь Symbian-подобный механизм со специальным порядком инициализации на куче, но это тоже будет костыль.
« Последнее редактирование: 04-02-2011 17:59 от Вад » Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #17 : 04-02-2011 18:46 » 

Вад, этот вопрос я тоже хотел задать, но у меня БОЛЬШАЯ проблема со знанием С.
поэтому библиотеку посмотрел вскольз.
например в Паскале есть такой оператор mark (если память не изменяет), который запоминает состояние кучи на момент вызова.) а затем можно вернуть все назад, вызвав соответствующий антиоператор, который все это освободит.
И мне показалось, что это реализовано в библиотеке CException.
Но при работе с микроконтроллерами работа с кучей это ВРЕДНО - памяти там для этого нет.
Я не говорю о монстрах с 64к на борту, а всего лишь 16К, ну или около того.
Offtopic:

А потом удивляемся - почему такие мелкие вещи используют такие мощные контроллеры
Поставлю в угол.
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #18 : 04-02-2011 19:31 » 

Пример неудачный. Если есть корректная призма - для чего проверять корректность треугольного основания?

Если бы данные всегда были гарантированно корректными, вопрос дефектов ПО вообще утратил бы актуальность. Но мы все еще живем в реальном мире. Где их брать, эти идеальные призмы?

А если нет - чего ради нам считать площадь этого основания, если призма уже некорректная?

У нас в програмном мире нет никаких призм. Есть набор параметров, полученных от клиента, и у нас нет оснований слепо им доверять. Нам нужно написать код, который ведет себя предсказуемо в любых условиях. Не забываем, что речь идет о встроенном софте, а не о студенческой лабораторной.

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

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

Если вы видели java-код с развесистым набором catch-ей, то не понимаю, как можно находить этот подход "лучше" и "красивее", чем обработка errno и возвращаемых значений.

Скажем так, я не фанат Java, мне ближе C#, но в данном случае это большой роли не играет, наверное.

Исключения нужно очень рано перехватывать

Кому нужно и зачем? Я предпочитаю перехватывать их в том месте, где их можно осмысленно обработать, а не просто передать код завершения дальше по цепочке вызовов в надежде, что им кто-то заинтересуется. И это совсем не обязательно "очень рано".

иначе что число вариантов исключений, что число возможных некорректных поведений программы, будет расти, и неважно, чего будет много: веток с проверкой, какой код ошибки в errno, или веток catch, проверяющих, какое, всё-таки, исключение из возможных 5 было сгенерировано.

Опять же совсем не факт. В отличие от CException, в Java и C# исключение - это объект, производный от базового класса исключений, и если построить дерево подклассов исключений с умом, можно единообразно обрабатывать целые семейства исключений, а не охотиться за каждым по отдельности.

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

Примерно то же можно при желании сказать об объектно-ориентированном программировании по отношению к структурному. А также о структурном программировании по отношению к GOTO, пожалуй. Можно писать отвратительные объектные программы и отвратительные структурные. Сам по себе инструмент совершенно ничего не значит, если его использование не следует определенной дисциплине.

Механизм исключений позволяет решить на самом деле очень важную задачу - произвести обработку ошибки в той точке программы, где это наиболее уместно, а не в той, где она возникла. Если его использовать как-то иначе, например, пытаясь перехватить исключение "очень рано", толку от них действительно будет немного. Тут я полностью согласен.

Мне кажется, что можно провести такую параллель с миром оборудования: исключение - это прерывание, а проверка кода ошибки - это опрос (поллинг). Какая система ведет себя логичнее: та, которая реагирует на события по прерываниям, или та, которая постоянно проверяет, не случилось ли чего?
Записан

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

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #19 : 04-02-2011 19:36 » 

Цитата
Мне кажется, что можно провести такую параллель с миром оборудования: исключение - это прерывание, а проверка кода ошибки - это опрос (поллинг). Какая система ведет себя логичнее: та, которая реагирует на события по прерываниям, или та, которая постоянно проверяет, не случилось ли чего?
Сбалансированная. С точки зрения работы приложения(девайса)
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #20 : 04-02-2011 19:37 » 

например в Паскале есть такой оператор mark (если память не изменяет), который запоминает состояние кучи на момент вызова.) а затем можно вернуть все назад, вызвав соответствующий антиоператор, который все это освободит.
И мне показалось, что это реализовано в библиотеке CException.
Не знаю точно, как реализована куча в Паскале, но явно на более высоком уровне, чем в С. Насколько я понимаю документацию на setjmp/longjmp, ничего такого оно не умеет, сохраняя лишь позицию указателя на стек, точку в коде и ещё некоторые регистры. Закрывать дескрипторы и освобождать память это не поможет.

Цитата
Но при работе с микроконтроллерами работа с кучей это ВРЕДНО - памяти там для этого нет.
Я не говорю о монстрах с 64к на борту, а всего лишь 16К, ну или около того.
Нет, ну для микроконтролеров я ничего и не говорю. Там, может, и не надо.
Хотя, тут можно и про те же дескрипторы вспомнить или взять другие случаи, когда надо будет сброс состояния какого-то делать...
Записан
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #21 : 04-02-2011 19:50 » 

например в Паскале есть такой оператор mark (если память не изменяет), который запоминает состояние кучи на момент вызова.) а затем можно вернуть все назад, вызвав соответствующий антиоператор, который все это освободит.
И мне показалось, что это реализовано в библиотеке CException.

Да, был такой в младших версиях Pascal. Там куча распределялась практически как стек, только навстречу ему - снизу вверх. Оператор mark попросту запоминал текущую верхушку кучи, а парный к нему release восстанавливал ее обратно, уничтожая все, что накопилось в куче между вызовами mark и  release. Для упрощенных компиляторов это было проще, чем следить за кучей.

В  CException ничего подобного нет, куча здесь не задействована. Используется другой механизм setjmp/longjmp, который относится к потоку управления, а не к данным.

Но при работе с микроконтроллерами работа с кучей это ВРЕДНО - памяти там для этого нет.

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

Я не говорю о монстрах с 64к на борту, а всего лишь 16К, ну или около того.

Это еще смотря какое семейство МК. У AVR, например, 16К - это как раз монстры, старшие модели. А у середнячков и килобайт не всегда наскребется. И у PIC вроде бы не лучше с этим.

Добавлено через 7 минут:
Ещё один минус - работа с памятью. Поскольку C - язык не так чтоб совсем объектный, подчищать динамически выделенные ресурсы после throw будет просто некому, и в таких случаях будут течи. Или будет неаппетитная очистка всех ресурсов перед каждым throw, что несколько испортит раздельные сценарии для Димки.

Можно следовать такому паттерну:
  • Создаем динамический объект.
  • Работаем с ним в защищенном блоке (Try).
  • Обрабатываем возможные ошибки (Catch).
  • Освобождаем динамический объект.

Вроде бы нет лазеек для утечки. Кто создает, тот и обязуется за собой подчистить кучу.

Ну и см. мой предыдущий ответ Sla: кучей не злоупотребляем без крайней на то необходимости.
« Последнее редактирование: 04-02-2011 19:57 от Dale » Записан

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

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #22 : 04-02-2011 19:59 » 

У нас в програмном мире нет никаких призм. Есть набор параметров, полученных от клиента, и у нас нет оснований слепо им доверять. Нам нужно написать код, который ведет себя предсказуемо в любых условиях. Не забываем, что речь идет о встроенном софте, а не о студенческой лабораторной.

Я лишь поставил под сомнение, на каком уровне модели должна выполняться проверка входных данных. Речь ведь идёт не о read-only коде.

При опросе нерадивый клиент может не проверить код ошибки и продолжить выполнение с некорректным результатом. Исключение принудительно прервет поток выполнения.
и куда уйдёт longjmp, если забыли сделать setjmp, а ошибка произошла, но не была протестирована? Что помешает устройству сломаться уже в руках покупателя?

Цитата
Механизм исключений позволяет решить на самом деле очень важную задачу - произвести обработку ошибки в той точке программы, где это наиболее уместно, а не в той, где она возникла. Если его использовать как-то иначе, например, пытаясь перехватить исключение "очень рано", толку от них действительно будет немного. Тут я полностью согласен.
Я полностью согласен. И механизм errno тоже позволяет это делать. И баланс между этими двумя соблюдать всё равно придётся, иначе будет Java/C#-быдлокод с кучей catch-ей на верхнем уровне, а при неумении препроцессора следить за "утекающими" из функций исключениями -- ещё и морока по поддержанию актуальной документации на все функции, способные эти исключения генерировать.

Механизм исключений - штука удобная для очень своих целей: когда ошибка может произойти на уровне, некомпетентном для её обработки. Но эта ошибка должна быть поистине фатальной и сложно- или непредсказуемой до погружения на оный уровень (исходя из внутреннего состояния программы). Ошибка ввода может и фатальна, но проста, предсказуема и вполне себе тестируема. Как и деление на ноль, например. Поэтому я не согласен с примером, а не потому, что мне вся идея целиком не нравится.

Идея - отличная. Но я не согласен с тем, что она позволяет писать более простой и надёжный код. Граблей здесь примерно столько же, а код проще не становится. Просто это другой способ мышления об ошибках, как вы абсолютно верно и заметили: вместо постоянной паранойи "тут может быть ошибка? проверяем, в случае чего - делаем return" получается схема "эта функция нам генерирует исключения? ага, пусть идут выше, а вот тут мы их перехватим и обработаем".  Вместо "рефлекторных" (ну, не совсем, но что-то в этом есть) проверок всего и вся - вдумчивая работа с документацией на функции (в противном случае всё пойдёт прахом).

Внимания такая техника требует, на мой взгляд, не меньше. На моей практике, багов с обработкой исключений в командных проектах было не меньше, чем с игнорированием или путаницей в кодах возврата. И баги были подчас куда более серьёзные.
« Последнее редактирование: 04-02-2011 20:05 от Вад » Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #23 : 04-02-2011 20:04 » 

ага..., давно в руки шашечек не брал (даташитов не читал), виноват - про память указанную мной на борту МК эту супермонстр. 

А вот исключения... это как раз и есть безопасный способ проверки входных данных.

Эта статься не рекомендация использования исключений, эта статья показывает как можно использовать исключения.

Честно... не люблю систему исключений... Она затрудняет (мне) чтение и понимание кода
Мне гораздо понятней в работе МК линейный код.
Но такие конструкции типа longjump использовать приходилось при вызове критических функций обработки данных.
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #24 : 04-02-2011 20:09 » 

Честно... не люблю систему исключений... Она затрудняет (мне) чтение и понимание кода
Мне гораздо понятней в работе МК линейный код.
Вот я тоже сегодня, когда пытался Димке объяснить суть моих претензий к идее "исключения на C", прежде всего пытался выразить, что я чувствую, когда подумаю, что строго императивный код вдруг посредине набора инструкций могут прервать и выдернуть на три уровня вверх в точку обработки. Интуитивную тревогу, вот что Улыбаюсь

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

Offtopic:
ЗЫ. В "Мотороле" мне расказывали легенду про чувака, у которого на C-шных макросах была построена система шаблонов (templates) а-ля C++, не говоря уже про ООП. Так что есть ещё горизонты Улыбаюсь
Поставлю в угол.
« Последнее редактирование: 04-02-2011 20:13 от Вад » Записан
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #25 : 04-02-2011 20:23 » 

Ошибка ввода может и фатальна, но проста, предсказуема и вполне себе тестируема. Как и деление на ноль, например. Поэтому я не согласен с примером, а не потому, что мне вся идея целиком не нравится.

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

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

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

Добавлено через 4 минуты и 54 секунды:
Честно... не люблю систему исключений... Она затрудняет (мне) чтение и понимание кода
Мне гораздо понятней в работе МК линейный код.

Не сложнее аппаратных прерываний, IMHO.Тут хотя бы точно знаешь точки, в которых может возникнуть исключение. А прерывания все равно от линейности кода не оставляют камня на камне.

Добавлено через 17 минут и 13 секунд:
Offtopic:
ЗЫ. В "Мотороле" мне расказывали легенду про чувака, у которого на C-шных макросах была построена система шаблонов (templates) а-ля C++, не говоря уже про ООП. Так что есть ещё горизонты Улыбаюсь
Поставлю в угол.

Хоть у нас тут и не Motorola, но дальнейшее предполагаемое развитие темы - как раз ООП на C. Потому что firmware подразумевает качественный софт, а качество без тестирования как-то трудно себе представить. Ну а дальше все по накатанной - какое же тестирование без всяких моков/фейков/стабов и т.д. Да и нормальный рефакторинг без объектной модели тоже немыслим. Так что это не оффтоп, а вполне реальная перспектива.
« Последнее редактирование: 04-02-2011 20:45 от Dale » Записан

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

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #26 : 04-02-2011 20:48 » 

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

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #27 : 04-02-2011 20:54 » 

А как же без прерываний? На опросе? В этих поллингах недолго и увязнуть с головой...
Записан

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

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #28 : 04-02-2011 21:02 » 

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

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #29 : 04-02-2011 21:18 » 

Аналогично исключения позволяют абстрагироваться от ошибок при написании основной программы. Если где-то что-то случилось - это обрабатывается в другом месте и к решаемой задаче непосредственного каательства не имеет.
Записан

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

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
Страниц: [1] 2  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines