Ружье достаточной огневой мощи, чтобы на нем повеситься

Путеводитель C++ программиста по неопределенному поведению

Паникуй!


Коротко о том, зачем и почему

Все начинается просто и незатейливо: обычный десятиклассник увлекается программированием, знакомится с алгоритмическими задачками, решения которых должны быть быстрыми. Узнает о языке C++, учит минимальный синтаксис, основные конструкции, контейнеры, решает задачи с предопределенным и всегда корректным форматом ввода и вывода, и горя не знает...

В это же время, где-то в большом мире, матерые разработчики каждый день ругают то одни языки программирования, то другие. По самым разным причинам: не удобно, нет какой-то возможности, много лишних букв писать, ошибки в стандартной библиотеке... Но есть язык, который ругают за все и особенно за такую непонятную и таинственную вещь как неопределенное поведение (undefined behavior, UB).

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

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


"Преждевременная оптимизация — корень всех зол" (Д. Кнут или Э. Хоар — в зависимости от того, какой источник смотрите). Язык С++, пожалуй, наиболее яркая тому демонстрация: огромное количество ошибок в C++ программах свзязаны с неопределенным поведением, заложенным в фундаменте языка просто для того, чтобы дать простор оптимизациям на этапе компиляции.

Если вы собираетесь писать на C++ код, в работоспособности которого хотите быть хоть немного уверенными, стоит знать о существовании различных подводных камней и ловко расставленных мин в стандарте языка, его библиотеке, и всячески их избегать. Иначе ваши программы будут работать правильно только на конкретной машине и только по воле случая.

Важно: этот сборник не является учебным пособием по языку и рассчитан на тех, кто уже знаком с программированием, с C++, и понимает основные его конструкции.


Содержание

  1. Как искать UB?
  2. Сужающие преобразования
  3. Целые и вещественные числа
    1. Переполнение знаковых целых чисел
    2. Числа с плавающей точкой
  4. Нарушения lifetime объектов
    1. Висячие ссылки — общие случаи
    2. Автовывод типов и висячие ссылки
    3. std::string_view
    4. Range-based for
    5. Cамоинициализация
    6. std::vector и инвалидация ссылок
    7. Висячие ссылки в лямбдах
  5. Неработающий синтаксис и стандартная библиотека
    1. Most Vexing Parse
    2. Const
    3. Конструкторы контейнеров
    4. std::move
  6. Исполнение программы
    1. Бесконечные циклы
    2. Рекурсия
    3. Ложный noexcept
  7. Происхождение указателей
    1. Невалидные указатели

И еще кое-что

Бегать за вами и ссудиться автор сего сборника не будет, но все-таки:

На этот проект можно ссылаться. Можно приводить примеры из него, со ссылками, конечно же.

Для копирования и иного воспроизведения надо получить согласие автора

Нельзя использовать в платных сервисах или взимать плату за обучение по этим материалам.

Copyright 2020-? Dmitry Sviridkin

Description
Путеводитель C++ программиста по неопределенному поведению
Readme 990 KiB
Languages
Markdown 100%