В последнее время я пытался понять, что такое правильное количество проверок и каковы правильные методы.
У меня есть несколько вопросов по этому поводу:
Как правильно проверить наличие ошибок (неверный ввод, плохие состояния и т. Д.)? Что лучше: явно проверять наличие ошибок или использовать такие функции, как утверждения, которые можно оптимизировать из окончательного кода? Я чувствую, что явно проверяю беспорядок в программе с большим количеством дополнительного кода, который не должен выполняться в большинстве случаев в любом случае - и не говоря уже о том, что большинство ошибок заканчиваются неудачей сброса / выхода. Зачем загромождать функцию явными проверками, чтобы просто прервать? Я искал утверждения против явной проверки ошибок и нашел немного, чтобы действительно объяснить, когда делать то или другое.
Большинство говорят: «используйте подтверждения для проверки логических ошибок и используйте явные проверки для проверки других ошибок». Это, кажется, не очень далеко от нас. Будем ли мы говорить, что это возможно:
Malloc returning null, check explictly
API user inserting odd input for functions, use asserts
Может ли это сделать меня лучше при проверке ошибок? Что еще я могу сделать? Я действительно хочу улучшить и написать лучший, «профессиональный» код.
источник
setjmp
/longjmp
доступны в C, поэтому вам не нужен новый язык.Ответы:
Для меня самый простой способ определить разницу - определить, было ли введено условие ошибки во время компиляции или во время выполнения. Если проблема заключается в том, что программист использует неправильную функцию, сделайте это утверждением, чтобы привлечь внимание к проблеме, но как только исправление скомпилировано в вызывающий код, вам больше не нужно беспокоиться о его проверке. Такие проблемы, как нехватка памяти или неправильный ввод данных пользователем, не могут быть решены во время компиляции, поэтому вы оставляете проверки.
источник
Проверяйте в любое время что угодно (это могло измениться после вашей последней проверки), что не на 100% под вашей командой. А также: во время разработки даже не доверяй себе! ;-)
Ококок ... «что-нибудь» предназначено для того, чтобы быть прочитанным как проверка на такие вещи, которые могут вызвать ненормальное прерывание или что-то, что может заставить ваше приложение / систему делать то, что он не должен делать.
Если серьезно, последняя часть последнего предложения важна, потому что она указывает на главный вопрос:
Если вы хотите построить стабильную систему, главное беспокойство не о том, что должна делать система, а о том, чтобы она могла делать такие обязательные действия, нужно позаботиться о том, чего она не должна делать, даже если она «загромождает» вашу код".
источник
Суть обработки ошибок не в том, поймешь ли и как. Это больше того, что вы делаете после того, как узнаете об этом .
Прежде всего - я бы сказал, что нет причин, по которым любая отдельная ошибка, возвращаемая подчиненным методом, не должна обрабатываться. А ошибки и исключения - это больше, чем возвращаемые значения или все try / catch.
Просто бросать и ловить недостаточно.
Посмотрите на это : где автор объясняет, что простое обнаружение, но бездействие потенциально подавляет исключение, и, если не будет сделано достаточно, чтобы устранить ущерб, - это хуже, чем просто допустить выполнение кода. Точно так же просто написание оператора «log» при открытии файла или ошибке чтения может помочь найти причину - но к тому времени, когда программа завершает работу, это может привести к повреждению данных! Недостаточно сказать, что у меня есть много попыток / поймать - более важно знать, что они действительно делают!
Не злоупотребляйте попыткой поймать.
Иногда - в основном ленивые или наивные программисты думают, что после написания достаточного количества try / catch их работа заканчивается и становится легкой. Довольно часто лучше применять корректирующие действия и возобновлять, чем просто сбрасывать все целиком. Если это невозможно, нужно решить, на какой уровень вам нужно вернуться. В зависимости от контекста и серьезности, попробуйте поймать вложенность требует тщательного проектирования. Например, увидеть это и это
Определите, кто несет ответственность:
Первое, что вы должны сделать, это определить, является ли ввод данных, передаваемых самой подпрограмме, просто неприемлемым (или пока не обработанным) сценарием или является исключением из-за окружения (например, системной проблемы, проблемы с памятью) или Является ли эта ситуация полностью внутренним результатом алгоритма. Во всех случаях - уровень, к которому вы можете вернуться, или действие, которое вы хотите предпринять, существенно различаются. В этом свете я хотел бы сказать - что когда вы запускаете код в рабочей среде, выполнение abort () для выхода из программы - это хорошо, но не для каждой мелочи. Если вы обнаружите повреждение памяти или нехватку памяти, это определенно, что даже после того, как вы приложите все усилия - все умрет. Но если вы получите нулевой указатель на входе - я бы не
Определите, каков наилучший возможный результат:
все, что должно быть сделано в условиях исключения, очень важно. Например, если в одном из наших случаев - медиаплеер обнаружит, что у него нет полных данных, которые должны быть воспроизведены для пользователя - что он должен делать?
Все это субъективно - и, возможно, есть больше способов справиться с проблемами, чем мы тривиально. Все вышеперечисленное требует построения и понимания глубины исключения, а также обеспечения возможности развития различных сценариев.
Иногда нам нужно проверять исключения, прежде чем они возникнут. Наиболее распространенным примером является ошибка деления на ноль. В идеале нужно проверить, что перед тем, как возникнет такое исключение - и если это так, - постарайтесь поставить наиболее подходящее ненулевое значение и двигаться дальше, а не совершать самоубийство!
Очистка. По крайней мере, это то, что вы должны сделать! Если случается, что функция открывает 3 файла, а четвертый не открывается - само собой разумеется, первые 3 должны были быть закрыты. Передача этой работы на уровень выше - плохая идея. если вы решили совсем не уходить без очистки памяти. И самое главное - даже если вы пережили исключение, сообщите об этом выше, что все пошло не так, как обычно.
То, как мы видим (нормальную) функциональность программного обеспечения в терминах различных иерархий или уровней или абстракций, так же, как мы должны классифицировать исключения на основе их серьезности, а также области, в которой они возникают, и они влияют на другие части системы - это определяет как обрабатывать такие разные исключения в лучшем виде.
Лучший справочник: Code Craft глава 6 - доступна для скачивания
источник
Проверять ошибки только во время отладочных сборок - это BAD IDEA (tm), компилируемый при выпуске, перекрывающий многократно используемые переменные в стеке, удаляющий защитные страницы, выполняющий сложные трюки с вычислениями, заменяющий тяжелые артриты предварительно вычисленными сдвигами и так далее.
Также используйте проверку ошибок в релизе, вы можете прибегнуть к чему-то простому:
Это также имеет очень хороший побочный эффект, который вы определенно не будете игнорировать ошибку, как только приложение начинает сбой на ПК Betta Testers.
Просмотрщики событий и журналы совершенно бесполезны по сравнению с тем
abort()
, кто их проверяет?источник
abort
разбивается на отладчик / создает дамп.exit
это плохо, да. Хотя я предпочитаю__asm int 3
больше всего.Различные вещи, которые вы можете сделать, это:
1. Читать и ассимилировать много кода в сети и посмотреть, как это делается. 2. Использовать
некоторые инструменты отладки, чтобы помочь вам найти области ошибок.
3. Помнить о тривиальных ошибках из-за неправильных назначений и синтаксические ошибки.
4. Некоторые худшие ошибки возникают из-за логических ошибок в программе, которые труднее найти. Для этого вы можете найти и найти, или для более сложных, попробуйте поговорить с людьми или использовать ресурсы, такие как Stackoverflow , Wikipedia , Google, чтобы получить помощь от люди.
источник