Как стать автором
Обновить
33
0

Программист

Отправить сообщение
Ну, сигнатура лямбды должна совпадать с сигнатурой функции, указатель на которую мы передаём, это разумеется.
Многие виды UB вызывают ворнинги в GCC и Clang.
Кстати, сейчас для определения UB во многих случаях можно писать constexpr-функции. По новому Стандарту UB недопустим в constexpr-функциях, поэтому код не скомпилируется.
Спасибо за лестный отзыв!
Я стараюсь писать о чём-то новом (в том числе и для себя), а не переписывать одно и то же другими словами. Но если узнаю что-то действительно новое про UB — постараюсь написать и об этом.
Я в курсе про точки следования (как они назывались до C++11, кстати), спасибо.

> Дело в том, что описания UB как раз отсутствуют в Стандарте.
Не согласен. Как раз именно в Стандарте все неопределённые ситуации и описаны в терминах UndB, UnspB и IDB. И все определения там есть, в самом начале.
Любопытно. А в каком компиляторе a==0, b==1?
Автор решил не приводить примеры неопределённого поведения, т.к. они подробно разжёваны, в том числе и на этом сайте. Автор всего лишь попытался показать разницу между undefined и unspecified behavior, о чём честно сказал в первом абзаце.

P.S.: я кстати не понял, где там в примере Unspecified behavior? a == 1, c == 0. Разве нет?
Так я и не рекламирую такой способ. Конечно, при написании нового кода есть варианты получше. ;)
Вызывать виртуальные функции из конструктора и деструктора вообще нельзя (вызов ведёт на ещё не построенный или уже разрушенный «верхний этаж»).

Не ведёт, т.к. применяется статическое связывание вместо динамического. Это уже обсуждалось в комментариях выше.
Хотя, в целом скорее соглашусь — проблема не завязана только на треды. Я лишь описываю достаточно типичный случай, когда с этой проблемой можно столкнуться, используя треды.
Честно говоря, не очень понял. В общем случае если вызвать виртуальный метод из конструктора, будет просто применено статическое связывание вместо динамического. В данном же случае вызывается именно run() из производного класса, что и приводит к проблемам.
Если я что-то не понял в комментарии, поясните пожалуйста.
Ну, если занудствовать, то треды вообще слабо вписываются в ООП. ))
Я представил самый простой вариант. Честно говоря, изначально в статье был ещё вариант с запуском треда и ожиданием на condition_variable, но я не увидел у него преимуществ по сравнению с обычной двухфазной инициализацией и удалил.
Я бы добавил ещё, что инициализация std::thread в списке инициализации конструктора — это почти всегда плохая идея.
class Some {
 public:
  Some() : thread_(std::thread([this](){ run(); })) {}
  void run();
 private:
  std::thread thread_;
  .............
};
Всё зависит от того, насколько часто вы читаете Стандарт, и как часто сообщения компилятора ставят вас в тупик. Если редко, то наверно необходимости особой нет. А, ну ещё вариант — если вы разрабатываете компилятор — тогда точно необходимо. :)
Любопытно. А можно ссылку на это интервью?
Первая часть статьи вводит в проблему, так сказать, рассматривает стандартные подходы и показывает, почему они не решают всех проблем. Кому-то это может быть очевидным, кто-то найдёт что-то новое для себя.

Что касается std::nested_exception — я рассматривал и их, но там всё же несколько про другое. Я думал некоторое время над тем, как решить проблему обработки множественных исключений, прилетающих из библиотечного кода, с помощью std::nested_exception, но придумать не смог. Этот механизм требует всё же изначально выбрасывать исключения не совсем стандартным способом. Если вам известно, как можно приспособить этот механизм для обсуждаемых в статье примеров, мне будет очень интересно его увидеть.

Информация

В рейтинге
Не участвует
Дата рождения
Зарегистрирован
Активность