Я надеялся, что кто-то сможет прояснить, что именно подразумевается под неопределенным поведением в C ++.
Технически, «неопределенное поведение» означает, что язык не определяет семантику для таких действий.
На практике это обычно означает " не делайте этого ; оно может сломаться, когда ваш компилятор выполняет оптимизацию, или по другим причинам".
Что меня озадачивает, так это , почему это работает и изменяет исходный объект const , но даже не выдает предупреждения с предупреждением, что это поведение не определено.
В этом конкретном примере попытка изменить любой не изменяемый объект может «работать» или перезаписать память, которая не принадлежит программе или принадлежит [части] некоторого другого объекта, поскольку Не изменяемый объект мог быть оптимизирован во время компиляции или он может существовать в некотором сегменте данных только для чтения в памяти.
Факторы, которые могут привести к этому, просто слишком сложны, чтобы их перечислять. Рассмотрим случай разыменования неинициализированного указателя (также UB): «объект», с которым вы затем работаете, будет иметь некоторый произвольный адрес памяти, который зависит от того, какое значение было в памяти в месте расположения указателя; что «значение» потенциально зависит от предыдущих вызовов программы, предыдущей работы в той же программе, хранения предоставленного пользователем ввода и т. д. Попытка рационализировать возможные результаты вызова Undefined Behavior просто невозможна, поэтому, опять же, мы обычно не вместо этого просто скажите " не делайте этого ".
Что меня озадачивает, так это то, что это работает и изменяет исходный объект const , но даже не выдает предупреждение с предупреждением, что это поведение не определено.
В качестве дополнительного усложнения компиляторам не требуется для диагностики (выдачи предупреждений / ошибок) для неопределенного поведения, поскольку код, который вызывает неопределенное поведение, не совпадает с кодом, который сформирован неправильно (то есть явно незаконный). Во многих случаях компилятор не может даже обнаружить UB, поэтому это область, в которой программист несет ответственность за правильное написание кода.
Система типов & mdash; включая существование и семантику ключевого слова const
& mdash; обеспечивает базовую защиту от написания кода, который может сломаться; программист C ++ всегда должен помнить, что это подрывает систему & mdash; например взломав const
ness & mdash; делается на свой страх и риск и, как правило, является плохой идеей. ™
Я могу представить себе случай, когда неосведомленность о том, что приведение в стиле C может привести к созданию const_cast
, может произойти незамеченной.
Абсолютно. С достаточно высокими уровнями предупреждений здравомыслящий компилятор может выбрать, чтобы предупредить вас об этом, но это не обязательно, а может и нет. В общем, это хорошая причина, по которой бросают вызовы в стиле C, но они все еще поддерживаются для обратной совместимости с C. Это просто одна из тех неудачных вещей.