Базовый курс C++ (MIPT, ILab). Lecture 11. Исключения

Поділитися
Вставка
  • Опубліковано 30 січ 2025

КОМЕНТАРІ • 45

  • @bochkarevartem
    @bochkarevartem 3 роки тому +31

    На 42 - 43 минуте сначала вызывается деструктор локальной копии Base, а потом уже деструктор оригинального Derived и его базы.
    А на лекции это звучит будто при наследовании первым вызывается деструктор базового класса.

    • @d7d1cd
      @d7d1cd 3 роки тому +21

      Тоже обратил на это внимание. До такой степени засомневался в своих знаниях порядка вызова деструкторов, что полез проверять. Только потом понял, что на видео сначала вызван деструктор срезанного до Base объекта, а потом объекта, сконструированного от Derived. Но изложение "сначала будет вызван деструктор Base, а потом Derived" несомненно путает.

    • @ilyakalinnikov4110
      @ilyakalinnikov4110 6 місяців тому

      @@d7d1cd аналогично)

  • @pavelrid
    @pavelrid 3 роки тому +12

    Летят два исключения. Одно говорит:
    - Жаль, погода нелетная.
    Другое:
    - Ничего. Лишь бы программист хороший попался.
    Спасибо за лекцию!

    • @LOL-nq3ky
      @LOL-nq3ky 2 роки тому +2

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

  • @bitrebus
    @bitrebus 2 роки тому +1

    42:40 Вы говорите: "т. е. на экране будет cначала деструктор ~Base, потом деструктор ~Derived, а потом деструктор Base для этого объекта, потому что это новый объект". Но деструкторы вызываются в порядке от дочерних к базовому. На самом деле объекты будут уничтожаться после обработки исключения в обратном порядке: сначала новый - Base, за ним старый - Derived.
    Base1() Derived1() Base2(const&)
    catch
    ~Base2() ~Derived1() ~Base1()

    • @ddvamp
      @ddvamp 2 роки тому +1

      Из стандарта [except.throw]#4

    • @tyzjar1
      @tyzjar1 2 роки тому +2

      Да, тоже это заметил и не полнеился написать код))) Было всё как вы сказали.

    • @atribolt
      @atribolt 5 місяців тому

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

  • @Konstantin_Evdokimov
    @Konstantin_Evdokimov Рік тому

    Линию Калба можно например границей (линией) исключений (exceptions border (line)) назвать, запомнить легче и сразу понятно что это.

  • @samolisov
    @samolisov 3 роки тому +1

    28:34 при переходе с 20 на 21 слайд, возможно я ошибаюсь, но фрейм с деструктором 0x...c70 уже же сняли, не должен ли обновиться адрес в this у деструктора на строчке #0 бэктрейса? Это ведь уже деструктор другого объекта.
    На мой взгляд пример на слайде 23 не такой уж и абсурдный, есть у нас какая-то математическая библиотека, на базе нее построили консольное приложение, там вывели в catch блоке сообщение на консоль. Завтра реализовали калькулятор с кнопочками и выводить ошибку будем в модальное окно. Важно, что в самой функции divide мы не знаем из какого типа приложения нас вызывают и поэтому нельзя взять и просто вывести на консоль, ее может и не быть.

    • @tilir
      @tilir  3 роки тому

      Интересный смысл для такой конструкции =)

  • @FeelUs
    @FeelUs 7 місяців тому

    17:00 разве при undefined instruction exception операционка не посылает какой-нибудь сигнал (который можно перехватить)?

    • @tilir
      @tilir  6 місяців тому

      Стандарт языка C++ ничего не знает про сигналы.

    • @FeelUs
      @FeelUs 6 місяців тому

      Ничего себе. Си знает, а с++ не знает. И что, есть какие-то системы, где есть с++, но нет си и сигналов?

    • @tilir
      @tilir  6 місяців тому

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

  • @trimo1120
    @trimo1120 Місяць тому

    У вас есть видео по кодировкам, им их преобразования? Например, я вообще не понимаю, почему в символах не используются unsigned char, а просто char, может дело, что включённый старший бит означает, что это не один символ в один бай, а ищи другой байт и также проверяй?

    • @tilir
      @tilir  Місяць тому

      Нет, таких видео у меня нет. Я пытался читать такие лекции, но на них все засыпали -- там масса довольно неинтересных деталей. Может быть рано или поздно я придумаю как это подать. К счастью в интернете много таких видео и на zerocost conf этого года было даже на русском.

  • @stanislavstanislavius7618
    @stanislavstanislavius7618 6 місяців тому

    Так что получается, нужно все заворачивать в try-catch?

  • @maximpahomov3977
    @maximpahomov3977 2 роки тому

    -На --1:26:00-- в цикле while (tmp.size() < used_) tmp.push(arr_[tmp.size()]), разве не должно быть tmp.push(arr_[tmp.used()], если size является аналогом capacity из стандартного вектора?-
    *UPD.* Увидел в следующей лекции, что size() возвращает used_.

  • @ddvamp
    @ddvamp 2 роки тому

    47:01 Ого! Интересно. Вопрос про разыменование null указателя заиграл новыми красками. Можно на собеседованиях покрасоваться.

    • @tilir
      @tilir  2 роки тому +1

      Ещё внутри noexcept-expression можно.
      godbolt.org/z/6dz3r6P36

  • @ИванРазинкин-д6в
    @ИванРазинкин-д6в 3 роки тому

    1:11:43 Можно уточнить, почему всё-таки будет исключение в copy ctor в цикле? Или это просто предположение а вдруг?

    • @tilir
      @tilir  3 роки тому +1

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

  • @RichardGraveman
    @RichardGraveman 9 місяців тому

    Что по стандарту должно произойти при двойном освобождении памяти?

    • @tilir
      @tilir  9 місяців тому +1

      UB

  • @ИванРазинкин-д6в
    @ИванРазинкин-д6в 3 роки тому

    Если я правильно понял технику линии Калба: мы создаем временный объект, с которым делаем все необходимые нам операции - выделение памяти и т.д., в течение которых может вылететь исключение - это все выше этой линии( не меняем состояние, а можем бросить исключение), а затем, лишь меняем этот временный объект с текущим. Вопрос, так действительно желательно(настоятельно рекомендуется) писать большинство классов(по типу как std::vector)?

    • @tilir
      @tilir  3 роки тому

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

  • @ddvamp
    @ddvamp 2 роки тому

    На 51:41 некорректная формулировка?. По [except.throw]#6#7 внутри catch блока исключение уже не активно.

    • @tilir
      @tilir  2 роки тому

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

  • @alexbur140
    @alexbur140 3 роки тому +1

    На 49 слайде разбирается, что 6-ой из 10 операторов присваивания Т может бросить исключение.
    А в строчке arr_= new T[rhs.size_] 6-ой из 10 конструкторов по умолчанию T также может бросить исключение.
    Про это ни слова не сказано.
    Я бы студентам рассказал про гарантии new и, в частности, для new[] (commit/rollback?).
    Со всем уважением! Но я, рожденный в стране советов, не могу удержаться от советов))

    • @tilir
      @tilir  3 роки тому

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

  • @frest4070
    @frest4070 6 місяців тому +1

    1:20:04 в цикле перед приращенем запятая вместо ;

    • @tilir
      @tilir  6 місяців тому

      Спасибо, добавил в errata.

  • @kirillgalitskiy233
    @kirillgalitskiy233 11 місяців тому

    1. Механизм исключительных ситуаций, в котором их понимает C++, тесно завязан на явном понимании/представлении, что такое стек вызовов...
    Абстрактная машина языка С++ никак, насколько я знаю, не описывает стеки вызовов и данных, поэтому при работе с исключениями возникают проблемы. Исключения бы стали самим самой разумеющимися, если бы язык давал явное описание фрейма функции.
    ua-cam.com/video/COEv2kq_Ht8/v-deo.html
    2. Механизм исключений по своему поведению очень похож на механизм goto, который не приветствуется в разработке. Оба этих механизма невероятные возможности изменения поведения программы, но требуют недюжего ума, чтобы уследить за всем...

    • @tilir
      @tilir  10 місяців тому

      1. Наоборот. То что стандарт даёт реализациям свободу в пределах очерченного абстрактной машиной в итоге позволило сделать исключения довольно эффективными.
      2. Исключения сложнее чем обычный goto, но гораздо проще, чем многопоточность. То есть это сложный но не слишком сложный механизм.

  • @niklkelbon3662
    @niklkelbon3662 3 роки тому

    Вроде бы оператор бул у стрима не равносилен good / bad, там всё несколько запутанней...

    • @tilir
      @tilir  3 роки тому +2

      Нет, там всё просто !(failbit || badbit). То есть это !fail(). В силу общей странности конструкции потоков там скорее вызов good() не означает, что всё хорошо. А вот на operator bool() можно ориентироваться, он работает интуитивно.

  • @xaoc3932
    @xaoc3932 9 місяців тому

    Вроде назван у курса 'базовый' но я все равно местамт не понимаю о чем идет речь, требуется знание предыдущих серий видимо. . )

    • @tilir
      @tilir  9 місяців тому

      А что именно не ясно?

    • @xaoc3932
      @xaoc3932 9 місяців тому

      Например 15:20 setjump and longjump
      Если я правильно написал. Такие слова в первый раз услышал

    • @tilir
      @tilir  9 місяців тому +1

      Да это из курса по языку C. Но я думаю это не так сложно нагуглить...

  • @deleteddeleted1940
    @deleteddeleted1940 2 роки тому

    1910

  • @meshcheriakov
    @meshcheriakov 2 роки тому

    Здравствуйте, могу ошибаться, пожалуйста проверьте 5-й слайд:
    atoi, atol, atoll - возвращает 0 в случае невозможности преобразования и в случае переполнения "behavior is undefined" ист. cppreference
    по atoi источник freebsd org : "ERRORS The function atoi() need not affect the value of errno on an error." В том же источнике характерные errno выставляет strtonum.
    "The HUGE_VALF, HUGE_VAL and HUGE_VALL macros expand to positive floating point constant expressions which compare equal to the values returned by floating-point functions and operators in case of overflow " , вероятно тогда общее описание на слайде подходит для преобразования в число с плавающей точкой strtod, strtof, strtold
    Спасибо за лекции!

    • @tilir
      @tilir  2 роки тому

      Да, надо заменить atoi на strtol, спасибо. Я смотрел в K&R B.5 где указано что atoi строго эквивалентна (int)strtol(s, (char **)NULL, 10). Но я сейчас глянул в C11 там поправили как вы сказали, сделав UB на ошибке.