salmer / CppDeveloperRoadmap

The roadmap for learning the C++ programming language for beginners and experienced devs.
https://salmer.github.io/CppDeveloperRoadmap
Other
2.94k stars 300 forks source link

Неопределённое поведение следует включить в первый этап вместе с отладкой #5

Closed yeputons closed 3 years ago

yeputons commented 3 years ago

С одной стороны, в первый этап включён отладчик:

изображение

С этим я согласен: надо уметь получать в итоге работающий код, а с первой попытки код работает редко. Отладчик очень сильно помогает.

С другой стороны, неопределённое поведение возникает только на третьем этапе, уже даже после ООП, правила трёх/пяти, ссылок, сырых указателей, утечек памяти:

изображение

Мне кажется, про неопределённое поведение надо рассказывать сразу же, как обучающийся может написать программу с UB. В противном случае интуитивное ожидание от программы с ошибкой — "произойдёт что-то логичное". Компьютеры же детерминированы и логичны. Да и на JavaScript/Java/Python/HTML/практически любом другом языке программирования ошибочная программа может выдать неверный ответ, зависнуть, упасть с исключением, но в любом случае проблему можно будет логично отследить до точки возникновения, а в подавляющем большинстве случаев укажут на строчку, где ошибка возникла.

В случае с C++ это категорически не так. Программа может падать, а отладчик может показывать на return 0; в main(), на int x = v.size(), на последнюю } в функции, на случайную } в программе после выхода за границу массива. Это всё сильно сбивают с толку обучающихся. К тому же фразы вроде "нельзя читать из неинициализированной переменной" даже при расскаже об UB первые несколько месяцев воспринимаются не как UB, а как "в неинициализированной переменной, очевидно, лежит просто какой-то случайный мусор". В частности, легко предположить, что если нам неважно, что там за мусор, то программа хотя бы не упадёт, но это неверно. Легко предположить, что если мы прочитали что-то за границей массива, то у нас либо прочитался мусор, либо всё сразу упало, а не упало через десять строк в вообще другой функции.

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

Я предлагаю передвинуть неопределённое поведение в первый этап и считаю, что без этого отлаживать программы на C++ становится сильно сложнее. Необязательно его изучать досконально, но необходимо перестать считать, что "очевидно же, что выход за границы массива так не проявится". Например, вот здесь есть хорошее введение (исходник).

DmitrievDmitriyA commented 3 years ago

Привет, мы тут поругались и думаем, что это резонное замечание. Решили к отладчику добавить заметку про то, что джунам стоит почитать о том, что такое UB. Саму ноду оставили на прежнем месте, потому что думается нам, что слишком глубоко джунов в UB вгонят не стоит рано. Пусть исследуют, когда наберутся опыта 👍🏻