asd

asd


Три дня без щитпостов. Скучали?

Сегодня расскажу вам про std::exception – почему они говно, почему они не говно, как делают в других языках и стоит ли их все-таки использовать?

Начнем с хорошего:

  1. Исключения – единственный способ явно сообщить об ошибке из конструктора
  2. Исключения трудно игнорировать
  3. Исключения визуально отделяют "хороший" код от "плохого", повышая тем самым читабельность кода

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

Теперь к минусам:

  1. Выбрасывание исключений из конструктора (п. 1 из плюсов) во многих компаниях считается плохим тоном. Потому что при выбрасывании исключения из конструктора, деструктор не будет вызван, что, в свою очередь, может привести к утечкам памяти.
  2. Так же исключения нельзя выбрасывать из деструкторов. Потому что в деструктор можно попасть во время раскрутки стека при уже выброшенном исключении, и если в этот момент будет выброшено ещё одно исключение, в результате будет вызван std::terminate(). Оно вам надо?
  3. Исключения могут нарушать структуру кода, создавая множество скрытых точек выхода, что затрудняет чтение и изучение кода. В некоторых компаниях этот минус решают через формальное требования код-стайла. В Яндексе, например, вот такое: "Не использовать исключения для control flow, использовать только для ошибочных ситуаций."
  4. Исключения в C++ очень медленные. Подробнее распинаться не буду, вот тут можно почитать – https://habr.com/ru/articles/279111/

А как делают другие языки?

1. В Go исключений вообще нет. Любая обработка ошибок выполняется примерно так:

file, err := ioutil.ReadFile("index.html")
if err != nil {
   // обработка ошибки
   return
}
// нормальное выполнение 

2. В Rust примерно та же история:

fn double_number(number_str: &str) -> Result<i32, ParseIntError> {

number_str.parse::<i32>().map(|n| 2 * n)

}


fn main() {

match double_number("10") {

Ok(n) => assert_eq!(n, 20),

Err(err) => println!("Error: {:?}", err),

}

}

3. А вот в Java исключения используются во весь рост:

try {

System.out.println(366/0);

} catch (ArithmeticException e) {

System.out.println("Ошибка!");

}

Вывод

Не буду томить, куча tier-0 компаний исключения не используют. Вот, например, Google Code Style https://google.github.io/styleguide/cppguide.html#Exceptions:

We do not use C++ exceptions.

И я не советую. Есть куча более простых способов сообщить об ошибке: опицоналы, туплы из результата и кода ошибки и т.п.

Report Page