Closed yeputons closed 3 years ago
Привет, мы тут поругались и думаем, что это резонное замечание. Решили к отладчику добавить заметку про то, что джунам стоит почитать о том, что такое UB. Саму ноду оставили на прежнем месте, потому что думается нам, что слишком глубоко джунов в UB вгонят не стоит рано. Пусть исследуют, когда наберутся опыта 👍🏻
С одной стороны, в первый этап включён отладчик:
С этим я согласен: надо уметь получать в итоге работающий код, а с первой попытки код работает редко. Отладчик очень сильно помогает.
С другой стороны, неопределённое поведение возникает только на третьем этапе, уже даже после ООП, правила трёх/пяти, ссылок, сырых указателей, утечек памяти:
Мне кажется, про неопределённое поведение надо рассказывать сразу же, как обучающийся может написать программу с UB. В противном случае интуитивное ожидание от программы с ошибкой — "произойдёт что-то логичное". Компьютеры же детерминированы и логичны. Да и на JavaScript/Java/Python/HTML/практически любом другом языке программирования ошибочная программа может выдать неверный ответ, зависнуть, упасть с исключением, но в любом случае проблему можно будет логично отследить до точки возникновения, а в подавляющем большинстве случаев укажут на строчку, где ошибка возникла.
В случае с C++ это категорически не так. Программа может падать, а отладчик может показывать на
return 0;
вmain()
, наint x = v.size()
, на последнюю}
в функции, на случайную}
в программе после выхода за границу массива. Это всё сильно сбивают с толку обучающихся. К тому же фразы вроде "нельзя читать из неинициализированной переменной" даже при расскаже об UB первые несколько месяцев воспринимаются не как UB, а как "в неинициализированной переменной, очевидно, лежит просто какой-то случайный мусор". В частности, легко предположить, что если нам неважно, что там за мусор, то программа хотя бы не упадёт, но это неверно. Легко предположить, что если мы прочитали что-то за границей массива, то у нас либо прочитался мусор, либо всё сразу упало, а не упало через десять строк в вообще другой функции.И это всё не считая проблем, которые могут возникнуть при висячих ссылках, ручном управлении памятью,
reinterpret_cast
.Я предлагаю передвинуть неопределённое поведение в первый этап и считаю, что без этого отлаживать программы на C++ становится сильно сложнее. Необязательно его изучать досконально, но необходимо перестать считать, что "очевидно же, что выход за границы массива так не проявится". Например, вот здесь есть хорошее введение (исходник).