На обеде "полистал" видео из вебинара PVS Studio: "Каждая идиома когда-то была проблемой" [0] (на скорости 1.75x вполне нормально).
Первая мысль по ходу просмотра: какой идиот придумал такой формат (видео, без содержания и без таймкодов) для материала с техническим уклоном?
Вторая мысль: 2 часа видео, даже на 1.75x - кошмар! Хорошо, что сейчас вторая половина 2026 и можно воспользоваться нейросетями.
Через Гигачат получил краткий пересказ-содержание с таймкодами [1], вот в таком виде с этим техническим материалом можно работать и потреблять интересные темы из него.
Судя по темам и той части видео, что я посмотрел - этот вебинар как раз то что надо для изучающих ЯП C++, это даст шанс мне не вляпаться в кучу C++-проблем, темы обсуждаются вполне общие (хотя на видео постоянно упоминается про разработку игр, это можно просто игнорировать).
Дублирую здесь краткое содержание вебинара (по таймкодам), которое сделал Гигачат [1]:
Вступление и цель вебинара
00:12–02:53: Приветствие. Спикеры — Александра Уварова (PVS-Studio) и Сергей Кушниренко (разработчик игровых движков). Тема: реальные ошибки в коде на C++ из открытых проектов, анализ с помощью статического анализа, разбор идиом для улучшения кода.
О PVS-Studio и анализе open-source проектов
02:46–03:57: Описание PVS-Studio, её роли в поиске ошибок, статистика по открытым проектам (более 17 тыс. найденных ошибок).
Примеры реальных проблем управления ресурсами
04:09–06:08: Пример утечки файла (DPTK), проблема двойного освобождения вектора (Telegram). Причина — ручное управление ресурсами.
RAII и его применение в геймдеве
06:21–10:33: Объяснение RAII (Resource Acquisition Is Initialization): история термина, как помогает избежать утечек ресурсов. Примеры использования в играх: стриминг, биндинг текстур, откат ненужных данных.
ScopeGuard и отложенное освобождение ресурсов
10:39–14:14: ScopeGuard — инструмент для автоматизации логики очистки при выходе из блока. В геймдеве часто используют списки отложенных действий, чтобы не снижать производительность горячего цикла.
Умные указатели (smart pointers) и их проблемы
22:00–27:05: Появление shared_ptr, unique_ptr после C++11; почему auto_ptr был неудачным экспериментом. Проблемы производительности и накладные расходы у shared_ptr. Особенности применения умных указателей в быстром коде игр.
Проблемы с циклическими ссылками и raw-приемами
27:00–28:50: Циклы ссылок между объектами приводят к утечкам памяти. Избегайте явного получения сырого указателя из shared_ptr.
Пример ошибки с типизацией smart pointer
28:20–29:11: Ошибка в Chromium: неправильный тип умного указателя приводит к неопределённому поведению при удалении массива через обычный delete.
Forward declaration и необходимость явного деструктора
29:34–32:26: При использовании forward-declaration важно явно объявлять деструктор класса и реализовывать его в .cpp-файле, иначе компилятор создаст некорректную реализацию удаления объекта.
Опасности неверного возврата ссылок
32:40–36:12: Возвращение ссылки на временный объект вызывает неопределённое поведение. Правильное решение — избегать лишних оптимизаций вручную или использовать copy elision.
Move-семантика и Resource Return
36:30–44:06: До C++11 отсутствовала семантика перемещения объектов. Теперь компиляторы могут перемещать объекты без копирования, что особенно полезно для строк, массивов, сложных структур. Обсуждаются нюансы реализации move-конструкции и возможные подводные камни.
Правила трёх/пяти функций для классов
52:16–58:12: Почему нужно реализовать все специальные функции класса (конструкторы копирования/перемещения, операторы присваивания, деструктор). Нарушение правил ведёт к ошибкам владения памятью и утечкам.
Некопируемые типы и паттерн NonCopyable
01:02:50–01:06:33: Объекты вроде мьютексов нельзя копировать — это нарушает их смысл. Паттерн NonCopyable запрещает копирование через пометку конструкторов и операторов как deleted.
Проблемы со стандартным пространством имен std::swap
01:09:23–01:14:01: Перегрузка swap внутри пространства std может привести к непредсказуемому поведению стандартных контейнеров. Лучше выносить такие перегрузки наружу или делать дружественными функциями.
Виртуальные функции в конструкторах/деструкторах
01:16:55–01:24:45: Вызывать виртуальные методы в конструкторах/деструкторах опасно: часть данных ещё не инициализирована либо уже разрушена. В геймдева проблему обходят двухэтапной инициализацией объектов.
Паттерны проектирования: Pimpl и Fast Pimpl
01:34:38–01:44:45: Pimpl позволяет скрывать реализацию классов за приватными структурами, упрощая замену библиотек (например, физику). Fast Pimpl избавляется от динамического выделения памяти ценой усложнения контроля выравнивания и размеров.
Синтаксические ловушки языка
01:45:45–01:52:30: Проблема most vexing parse: выражение вида Hit x() воспринимается как объявление переменной, а не вызов функции. Это легко возникает при рефакторинге.
Заключение
01:52:50–01:55:05: Вебинар завершён. Предложен промокод на пробу статического анализатора, приглашение подписаться на блог Сергея, благодарность участникам.
Основные выводы:
Многие современные идиомы программирования возникли как решения конкретных проблем безопасности и эффективности. Статический анализ реально находит критичные ошибки даже в крупных проектах. Грамотное использование RAII, scope guard, умных указателей и move-семантики снижает вероятность утечек и ошибок владения. Для стабильного API рекомендуется применять паттерны типа Pimpl. Важно соблюдать правила трёх/пяти функций для корректной работы пользовательских типов.
[0] https://rutube.ru/video/4b907ec9764a7b113c1f23143166897f/