#cpp #c
Неопределенное поведение, мягко говоря, неоднозначное решение в дизайне языка. Тем не менее с этим злом приходится жить миллионам программистам. В стандарте, ситуации в которых возникает неопределенное поведение, описаны очень тяжелым техно языком. Неудивительно что большое количество программистов, да что там основная масса, просто не читали стандарт, а если и читали то одну половину не поняли, а вторую забыли. Самое страшное не столько в том, что неопредленное поведение вообще допускается стандартом или что оно достаточно широко распространено. А в том, что в жизни рядовой программист плохо понимает когда оно вообще возникает. Тем более разочаровывает то, что разработчики компиляторов не стремятся помочь своему клиенту рядовому программисту хотя могли бы, христоматийный пример: int i = 0; i = ++i + i++; Вот этот код мой MSVC съедает молча. Есть еще не мало ситуаций когда компилятор мог бы предупредить программиста.
Ответы
Ответ 1
Почему не сообщают? Потому что не обязаны. Тем не менее некоторые компиляторы могут сообщать о некоторых ситуациях, которые могут приводить к неопределённому поведению. Так, если собрать код из вопроса с помощью GCC или clang, Вы получите предупреждение. Есть и другие ситуации, которые покрыты компиляторами, но не все. Для других ситуаций существуют всевозможные статические анализаторы, типа того же PVS Studio, clang-tidy (встроен в CLion & Resharper++) и прочих.Ответ 2
Предлагаю взглянуть на неопределенное поведение немного под другим углом: в большинстве случаев возникновения неопределенного поведения непосредственно в языковых конструкциях, оно является нарушением со стороны программиста некоторых закрепленных в стандарте требований, без наличия которых эти конструкции вообще не могли бы существовать в нынешнем варианте языка. Другими словами, компилятору прямо позволено рассчитывать, что программист не будет делать некоторых вещей, потому что написание компилятора без такого послабления не представляется возможным. Простой пример: void Inc(int & x) { x += 1; } Тут кусок x += 1; подразумевает целый букет потенциальных неопределенных поведений: x может быть ссылкой на невалидный объект x может быть ссылкой на объект другого типа (ака strict aliasing violation) x может быть ссылкой на валидный объект, но являющийся частью объекта с const квалификатором к значению x будет производится доступ из других потоков при добавлении 1 произойдет целочисленное переполнение Никаких вариантов действий, кроме как предположить, что ничего плохого тут не произойдет, у компилятора нет. Почему язык пришел к такой ситуации - это другой вопрос. Надо полагать, что большая часть проблем такого рода происходит еще из С.Ответ 3
Это может быть легаси и/или код, заточенный под определенный компилятор (в том числе автоматически сгенерированный). Ведь поведение не определено лишь с точки зрения стандарта, а у компилятора/платформы всегда есть конкретный ответ на любой вопрос.
Комментариев нет:
Отправить комментарий