Здравствуйте, Nikе, Вы писали:
_>>>Нуу в каком-то смысле в C++ заменой finally и т.п. могут быть просто {} скобки... EP>>В каком смысле "просто {} скобки" заменяют finally? N>Деструкторы обязательно отработают -> finally не нужен.
да не, товарищ точно что-то другое имел ввиду — он же говорит про какие-то "просто {} скобки".
Здравствуйте, jazzer, Вы писали:
J>А на самом деле внутри твоей функции ReadProfile зовется еще 50 функций на 10 уровнях вложенности. И ни одна из них, заметь, не способна обработать ошибку на своем уровне, и ей остается лишь передать ошибку на верхний уровень, который способен принять решение "Не считалось? Ну и хрен с ним, создадим новый".
Ну то есть мы возвращаемся к исходному тезису "а что же такое ошибка?"
Вот в тех 50 ыункциях, например, будет поиск каталога, открытие файла, чтение даных, их разбор.
Что будет из этого кидать исключения? провалившееся открытиые файла? Устаревшая версия формата данных в файле? В смысле разборщик данных, задетективший устаревшую версию? Что-то ещё?..
Фишка-то как раз в том, что пока мы не можем обработтать особую ситуацию мы обычно не знаем ошибка это или штатная версия поведения кода. А там, где уже знаем, обычно и обработать можем...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
L>>По существу мы как раз от тебя ничего не дождались. E>ищите и обрящете...
Не стоит искать смысл, там где его нет. У меня сложилось мнение, что в данной теме ты просто троллишь, выдумываешь сферических коней и просишь их обосновать.
Здравствуйте, jazzer, Вы писали:
J>Такого не будет. Приложение входит в режим завершения и корректно выключается. J>Памяти на логирование хватит.
На кой для этого вообще исключения, а не exit, например?.. E>>Чем это вообще отличается от старой доброй сишной схемы?
E>>Тут схема, когда отгрузку/рестарт по нехватке памяти мы прописываем явно намного прямее J>Куда уж прямее
Ну прямее, это когда мы по onexit или какому-то аналогу регим чего нам аварийно надо спасти в случае если уже пора, а потом просто зовём exit или аналог и всё...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, MTD, Вы писали:
MTD>Не стоит искать смысл, там где его нет. У меня сложилось мнение, что в данной теме ты просто троллишь, выдумываешь сферических коней и просишь их обосновать.
Если ты не заметил, я задал простой вопрос. На кой нужна базовая гарантия...
Ответов пока не наблюдаю.
Да, мой от вет прост -- она не нужна.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
T>>Типичный обработчик обрабатывает конкретную ошибку, а не все подряд. Во первых, если все тухло, то спасать уже нечего. E>Обычно хотят спасти данные пользователя + получить адекватную отладочную инфу...
На этот случай делается подушка + специальный режим работы, который работает медленно но максимально надежно.
T>>При чем так должен делать не только твой, но и чужой код, типа бустов, стл и тд. T>>Самое главное — в итоге, когда все это приобретет законченый вид, вдруг оказывается, что код обработки ошибок делает ровно то же, что и исключения, только явно.
E>Почему7 В С же как-то жили? По доступу к нулю будет сегфолт, в его обработчике спасут критические данные и запишут в корку отладочную инфу...
Здравствуйте, Tanker, Вы писали:
E>>Почему7 В С же как-то жили? По доступу к нулю будет сегфолт, в его обработчике спасут критические данные и запишут в корку отладочную инфу...
T>В С++ это тоже возможно.
Конечно возможно.
Просто, если помнишь, я высказал сожаление, что хотя вот нехватка памяти как раз такое событие, для исключений, но его прямее получается обрабатывать в чисто сишном ключе...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, jazzer, Вы писали:
J>>А на самом деле внутри твоей функции ReadProfile зовется еще 50 функций на 10 уровнях вложенности. И ни одна из них, заметь, не способна обработать ошибку на своем уровне, и ей остается лишь передать ошибку на верхний уровень, который способен принять решение "Не считалось? Ну и хрен с ним, создадим новый". E>Ну то есть мы возвращаемся к исходному тезису "а что же такое ошибка?"
Ага, причем тезис был мой
E>Вот в тех 50 ыункциях, например, будет поиск каталога, открытие файла, чтение даных, их разбор. E>Что будет из этого кидать исключения? провалившееся открытиые файла? Устаревшая версия формата данных в файле? В смысле разборщик данных, задетективший устаревшую версию? Что-то ещё?.. E>Фишка-то как раз в том, что пока мы не можем обработтать особую ситуацию мы обычно не знаем ошибка это или штатная версия поведения кода. А там, где уже знаем, обычно и обработать можем...
Вот там, где знаем, там и обрабатываем исключения или пользуемся небросающим интерфейсом (но к исключениям в любом случае надо быть готовым).
Логика очень простая: функция должна выполнить некое задание, которое ей дает вызывающий код.
Если она это задание выполнить не может, она бросает исключение.
Вот и все.
Соответственно функция ReadProfile при проблеме с файлом не может выполнить приказ "прочитать профиль из файла" и бросает исключение.
А функция ReadProfileOrCreateNew — может наплевать на файл, если с ним что-то не так, и попробовать создать новый профиль. Но если с новым профилем тоже облом выйдет — она тоже бросит исключение, которое будет означать "не смогла ни прочитать, ни новый создать".
Т.е. open_file(path) должна бросать исключение, если файла нет. Но при этом может параллельно существовать небросающий интерфейс, например, bool file_can_be_open(path, mode), bool path_is_well_formed(path).
Здравствуйте, Erop, Вы писали:
E>Конечно возможно. E>Просто, если помнишь, я высказал сожаление, что хотя вот нехватка памяти как раз такое событие, для исключений, но его прямее получается обрабатывать в чисто сишном ключе...
По твоему исключения SEH, как ты предложил, это сишный подход ? Т.е. ты видишь серьезные отличие между try catch и __try __except ? Я даже и не знаю, как быть.
Здравствуйте, Erop, Вы писали:
E>Ну прямее, это когда мы по onexit или какому-то аналогу регим чего нам аварийно надо спасти в случае если уже пора, а потом просто зовём exit или аналог и всё...
Все правильно. Для этого в С++ есть set_new_handler.
Здравствуйте, Patalog, Вы писали:
P>ЗЫ Судя по всему тебе не интересно обсуждение, тебе интересно погыгыкать.
На самом деле я просто смотрю сколько народа готово использовать исключения даже в приведённом мною случае. И каждый высказавшийся за это увеличивает моё согласие с решением разных компаний забанить исключения в целом. Понятна моя мысль? )
Здравствуйте, Patalog, Вы писали:
P>Я не понимаю, что значит "должны приводить к глубокой раскрутке стека". Ошибки никому ничего не должны, наоборот их должны обрабатывать.
См. ниже.
P>Кто, как и где — вопрос выбора в каждом конкретном случае, я лично затрудняюсь дать общие рекомендации. P>Возвращаясь к своему примеру анализатора входных данных под заданную спецификацию формата - P>парсим нек. заголовок -> опс, нарушение констрейнов (значение должно быть меньше Х) -> обработка — добавляем к списку ошибок P>парсим нек. заголовок -> опс, по нек. признакам делаем вывод что это говно какое-то -> исключение -> на уровне где происходит отделение мух от котлет, ловим, записываем и пытаемся пересинхронизироваться, т.е. найти след. sync word. Пытаться обработать ошибку на том же кровне где мы поняли что данные тотально "не те" — значить пытаться упорно найти нужным нам заголовок не понятно из чего, забить список ошибок нерелевантными сообщениями и обтормозить весь процесс. Пытаться там же пересинхронизироваться — размывать логику разбора, размывать ответственность, протаскивать ненужный контекст.
При нормальном проектирование модульности обработка ошибок в большинстве случаев будет идти на предыдущем уровне стека вызовов. А в тех редких случаях, когда это не так, как раз и есть смысл использовать исключения.
P>Практика конечно у всех разная, у меня не было прецендентов усложнения из-за исключений. Обратные преценденты были. P>В том числе и с "заменой кодов возврата" (что в принципе порицается) — нужно было протаскивать коды возврата из 3d party, из самой глубины на самый вверх, вплоть до JS скрипта живущего на хтмл странице. Я выкинул всю гору лапши /if(e) return e;/ по всему стеку вызовов (довольно глубоких) и заменил на throw класса который хранит код ошибки (если точнее это boost::system::system_error). Чем очень облегчил себе жизнь и _уменьшил_ объем кода.
Вот вы написали что не понимаете про глубину стека и тут же приводите буквально идеальный пример этого. Причём замечу что даже с использование того же слова ("протаскивать коды возврата из самой глубины на самый вверх"). У вас как раз тот самый необычный случай, когда вся обработка идёт только на самом высоком уровне — идеальное применение исключений.
Здравствуйте, minorlogic, Вы писали:
M>Так и источников ошибок на самом деле не так много. А все остальное это логика работы она же управляющая логика. Обычно управляющая логика обменивается результатами сквозь 1 уровень и имеет жесткую смысловую нагрузку.
Конечно. Просто частенько говорят что-то вроде "функция возвращает ошибку в случае неудачи". Хотя в контексте исполнения программы это совсем не ошибка даже. Это вопрос так сложившейся терминологии...
Здравствуйте, landerhigh, Вы писали:
L>Объект Шредингера после вызова конструктора — это, конечно, треш и угар. Но тут и обсуждать нечего — только в переплавку.
Ну да, вне зависимости от нашей дискуссии об исключениях, Tizen api всё равно останется весьма странным. )))
L>По поводу исключений из конструктора: конструктор объекта обязан выкинуть исключение, как только возникает ситуация, делающее существование объекта бессмысленным. Это бывает далеко не так часто, но вовсе не ограничивается обломом с выделением памяти. Например — вектор без памяти никому не нужен. Класс FileLogger на машине без доступной для записи файловой системы тоже. OpenGLRenderer никому не нужен, если нет его поддержки. И так далее. Но все это — именно исключительные ситуации; полагаться исключительно на исключения для обработки таких ошибок не следует, это в некотором смысле последняя линия обороны.
Мммм на мой взгляд правильнее решать эти задачи с точки зрения правильной архитектуры, а не таких убойных вещей как исключения. А точнее логичнее сделать у подобных классов приватный конструктор (без всяких исключений и двух фаз) и создавать их только своей функцией, которая умеет в начале проверить что все необходимые возможности железа и т.п. присутствуют.
Жаль только с выделением памяти такой фокус не прокатывает. Точнее технические то можно (собственно new — как раз и есть такая особая функция), но тогда во-первых будет дико загромождённый код, а во-вторых обработка нехватки памяти в любом случае сводится к очень специфичным делам. Так что тут по любому исключения хороши.
Здравствуйте, jazzer, Вы писали:
E>>Ну то есть мы возвращаемся к исходному тезису "а что же такое ошибка?" J>Ага, причем тезис был мой
Ну тут у разных сторон есть разные ответы на этот вопрос
J>Логика очень простая: функция должна выполнить некое задание, которое ей дает вызывающий код. J>Если она это задание выполнить не может, она бросает исключение. J>Вот и все.
То есть исключения -- это уже не ошибка, поле которой мы то ли отгружаемся, то ли сохраняемся и отгружаемся, а обычня часть интерфейса функции. Так?
Не жалко процедурного стиля программирования и слабейшего предусловия с ним?..
J>Т.е. open_file(path) должна бросать исключение, если файла нет. Но при этом может параллельно существовать небросающий интерфейс, например, bool file_can_be_open(path, mode), bool path_is_well_formed(path).
То, что true из file_can_be_open(path, mode), не гарантирует возможности открыть файл, так как это два РАЗНЫХ запроса, между которыми может вклиниться другой потокЪпроцесс/компьютер не смущает?..
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, jazzer, Вы писали:
J>Вот там, где знаем, там и обрабатываем исключения или пользуемся небросающим интерфейсом (но к исключениям в любом случае надо быть готовым). J>Логика очень простая: функция должна выполнить некое задание, которое ей дает вызывающий код. J>Если она это задание выполнить не может, она бросает исключение. J>Вот и все. J>Соответственно функция ReadProfile при проблеме с файлом не может выполнить приказ "прочитать профиль из файла" и бросает исключение. J>А функция ReadProfileOrCreateNew — может наплевать на файл, если с ним что-то не так, и попробовать создать новый профиль. Но если с новым профилем тоже облом выйдет — она тоже бросит исключение, которое будет означать "не смогла ни прочитать, ни новый создать". J>Т.е. open_file(path) должна бросать исключение, если файла нет. Но при этом может параллельно существовать небросающий интерфейс, например, bool file_can_be_open(path, mode), bool path_is_well_formed(path).
Вы очень хорошо обосновали почему и как тут можно использовать исключения. Собственно с этим никто и не спорил. Вопрос в том зачем их тут использовать, если решение без них работает как минимум не хуже. Принцип Оккама как бы никто не отменял...
Здравствуйте, Tanker, Вы писали:
T>По твоему исключения SEH, как ты предложил, это сишный подход ?
Я где-то предлагал SEH? Это ты про сегфолт что ли? Поверх SEH можно сделать обработку похожую на сигналы, но весь SEH для этого не нужен
T> Т.е. ты видишь серьезные отличие между try catch и __try __except ?
Конечно вижу. Обработчик SEH может вызвать terminate() ДО раскрутки стека
T>Я даже и не знаю, как быть.
Ну учить мат часть, наверное?..
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, jazzer, Вы писали:
J>Все правильно. Для этого в С++ есть set_new_handler.
Так я же не спорю. Я только за. Я всего лишь показываю, что вот как раз конец памяти по исключению обрабатывать стрёмно... Лучше по-сишному...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском