Рубрика «exception»

C++23 — финал, C++26 — начало - 1

С момента моей прошлой публикации состоялось уже две встречи международного комитета по стандартизации C++.

Комитет занимался полировкой C++23:

  • static operator[];
  • static constexpr в constexpr-функциях;
  • безопасный range-based for;
  • взаимодействие std::print с другими консольными выводами;
  • монадический интерфейс для std::expected;
  • static_assert(false) и прочее.

И прорабатывал новые фичи C++26:

  • std::get и std::tuple_size для агрегатов;
  • #embed;
  • получение std::stacktrace из исключений;
  • stackful-корутины.

Читать полностью »

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

Один из наиболее распространённых неудачных подходов — это использование исключений для контроля потока выполнения. Этого следует избегать по двум причинам:

  1. Это снижает производительность и быстродействие вашего кода
  2. Это делает ваш код менее читаемым

Читать полностью »

Существуют различные способы обработки ошибок в языках программирования:

  • стандартные для многих языков исключения (Java, Scala и прочий JVM, python и многие другие)
  • коды статуса или флаги (Go, bash)
  • различные алгебраические структуры данных, значениями которых могут быть как успешные результаты так и описания ошибок (Scala, haskell и другие функциональные языки)

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

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

Сразу отбросим использование кодов и флагов, так как этот подход не принят в JVM языках и по моему мнению слишком подвержен ошибкам (прошу прощения за каламбур). Поэтому будем сравнивать исключения и разные виды АТД. Кроме того АТД можно рассматривать как использование кодов ошибок в функциональном стиле.

UPDATE: к сравнению добавлены исключения без стек-трейсов

Читать полностью »

[DotNetBook] Время занимательных историй: исключительно исключительные ситуации - 1

Существует ряд исключительных ситуаций, которые скажем так… Несколько более исключительны чем другие. Причем если попытаться их классифицировать, то как и было сказано в самом начале главы, есть исключения родом из самого .NET приложения, а есть исключения родом из unsafe мира. Их в свою очередь можно разделить на две подкатегории: иcключительные ситуации ядра CLR (которое по своей сути — unsafe) и любой unsafe код внешних библиотек.

Давайте поговорим про эти особые исключительные ситуации.

ThreadAbortException

Вообще, это может показаться не очевидным, но существует четыре типа Thread Abort.

Данная статья — третья из четырех в цикле статей про исключения. Полный цикл:
Архитектура системы типов
Cобытия об исключительных ситуациях
Виды исключительных ситуаций (эта статья)
— Сериализация и блоки обработки

Читать полностью »

[DotNetBook] События об исключительных ситуациях и как на пустом месте получить StackOverflow и ExecutionEngineException - 1 С этой статьей я продолжаю публиковать целую серию статей, результатом которой будет книга по работе .NET CLR, и .NET в целом. За ссылками — добро пожаловать по кат.

События об исключительных ситуациях

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

    try {
        // ...
    } catch {
        // do nothing, just to make code call more safe
    }

В такой ситуации может оказаться что выполнение кода уже не так безопасно как выглядит, но сообщений о том что произошли какие-то проблемы мы не имеем. Второй вариант — когда приложение глушит некоторое, пусть даже легальное, исключение. А результат — следующее исключение в случайном месте вызовет падение приложения в некотором будущем от случайной казалось бы ошибки. Тут хотелось бы иметь представление, какая была предыстория этой ошибки. Каков ход событий привел к такой ситуации. И один из способов сделать это возможным — использовать дополнительные события, которые относятся к исключительным ситуациям: AppDomain.FirstChanceException и AppDomain.UnhandledException.

Данная статья — первая из четырех в цикле статей про исключения. Полный цикл:
Архитектура системы типов
Cобытия об исключительных ситуациях (эта статья)
— Виды исключительных ситуаций
— Сериализация и блоки обработки

Читать полностью »

[DotNetBook] Исключения: архитектура системы типов - 1 С этой статьей я продолжаю публиковать целую серию статей, результатом которой будет книга по работе .NET CLR, и .NET в целом. За ссылками — добро пожаловать по кат.

Архитектура исключительной ситуации

Наверное, один из самых важных вопросов, который касается темы исключений — это вопрос построения архитектуры исключений в вашем приложении. Этот вопрос интересен по многим причинам. Как по мне так основная — это видимая простота, с которой не всегда очевидно, что делать. Это свойство присуще всем базовым конструкциям, которые используются повсеместно: это и IEnumerable, и IDisposable и IObservable и прочие-прочие. С одной стороны, своей простотой они манят, вовлекают в использование себя в самых разных ситуациях. А с другой стороны, они полны омутов и бродов, из которых, не зная, как иной раз и не выбраться вовсе. И, возможно, глядя на будущий объем у вас созрел вопрос: так что же такого в исключительных ситуациях?

Читать полностью »

Как известно из функциональных интерфейсов в Stream API нельзя выбрасывать контролируемые исключения. Если по каким-то причинам это необходимо (например, работа с файлами, базами данных или по сети), приходится оборачивать их в RuntimeException. Это неплохо работает если ошибки игнорируются, но если их необходимо обрабатывать, то код получается громоздкий и трудночитаемый. Я заинтересовался можно ли объявлять интерфейсы и методы с generic исключениями и неожиданно для себя узнал, что можно.

Зададим такой функциональный интерфейс, от стандартного интерфейса Function<A, B> он отличается только наличием третьего generic-типа для бросаемого исключения.

public interface ThrowableFunction<A, B, T extends Throwable>{
	B apply(A a) throws T;
}

И объявим простенький метод, который преобразует коллекцию используя этот интерфейс, у этого метода также объявлен generic-тип для бросаемого исключения (совпадающий с типом исключения которое может выбросить функциональный интерфейс).

public static <A, B, T extends Throwable> Collection<B> map(Collection<A> source, ThrowableFunction<A, B, T> function) throws T {
	Collection<B> result = new ArrayList<>();
	for (A a : source) {
		result.add(function.apply(a));
	}
	return result;
}

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

image

Предлагаю вашему вниманию перевод оригинальной статьи Роберта С. Мартина.

За последние несколько месяцев я попробовал два новых языка. Swift и Kotlin. У этих двух языков есть ряд общих особенностей. Действительно, сходство настолько сильное, что мне стало интересно, не является ли это новой тенденцией в нашей языкомешалке. Если это действительно так, то это тёмный путь.

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

Проблема в том, что оба языка сделали ставку на сильную статическую типизацию. Кажется, оба намерены заткнуть каждую дыру в своём родном языке. В случае со Swift – это странный гибрид C и Smalltalk, который называется Objective-C; поэтому, возможно, упор на типизацию понятен. Что касается Kotlin – его предком является уже довольно строго типизированная Java.

Я не хочу, чтобы вы думали, что я против статически типизированных языков. Я не против. Есть определенные преимущества как для динамических, так и для статических языков; и я с удовольствием пользуюсь обоими видами. Я предпочитаю динамическую типизацию, и поэтому я иногда использую Clojure. С другой стороны, я, вероятно, пишу больше Java, чем Clojure. Поэтому вы можете считать меня би-типичным. Я иду по обеим сторонам улицы — если так можно выразиться.

Дело не в том, что меня беспокоит, что Swift и Kotlin статически типизированы. Скорее меня беспокоит глубина статической типизации.Читать полностью »

Продолжаем перевод серии статей об обработки исключений в C++

1 часть
2 часть

C++ exceptions под капотом: поиск верного landing pad

Это уже 15-я глава в нашей длинной истории. Мы уже изучили достаточно много о том, как работают исключения, и даже имеем написанную работающую собственную персональную функцию с небольшим количеством рефлексии, определяющей где находится catch-блок (landing pad в терминах исключений). В прошлой главе мы написали персональную функцию, которая может обрабатывать исключения, но она всегда подставляет только первый landing pad (т.е. первый же catch-блок). Давай те улучшим нашу персональную функцию, добавив возможность выбирать правильный landing pad в функции с несколькими catch-блоками.
Читать полностью »

Продолжаем перевод серии статей об обработки исключений в С++

1 часть
3 часть

C++ exceptions под капотом: милая персональность

Наша поездка в удивительном путешествии изучения работы исключений еще далека от конца, нам еще предстоит изучить что-то называемое "call frame information", помогающая библиотеке Unwind делать разворачивание стэка, а так же что компилятор пишет в чем-то, называемом LSDA, в которой определяется, какие ошибки метод может обрабатывать. А так же мы уже узнали, что большинство магии происходит в персональной функции, которую мы пока еще не видели в действии. Давай те резюмируем, что мы уже знаем о пробросе и отлове ошибок (или, точнее, что мы уже знаем о том, как брошенное будет перехвачено):

  • компилятор транслирует throw объявление в пару cxa_allocate_exception/xca_throw
  • __cxa_allocate_exception создает исключение в памяти
  • __cxa_throw запускает работу разворачивания и передает исключение в низко-уровневую библиотеку разворачивания, вызывая _Unwind_RaiseException
  • Разворачивание стэка использует CFI, чтобы узнать, какая сейчас функция в стеке
  • Каждая функция имеет LSDA, добавляя что-то, называемое .gcc_except_table
  • Разворачивание вызывает персональную функцию с текущим фреймом стэка и LSDA, которая должна продолжить разворачивать стэк, если текущая функция не имеет обработчиков исключения данного типа.

Читать полностью »


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js