Когда был написан Стандарт, большинство форм «неопределенного поведения» признавали тот факт, что реализации, предназначенные для разных платформ и целей, будут вести себя по-разному - некоторые полезны и предсказуемы, а другие нет, и признавали, что «рынок»[как это описывается в документе C Rationale] было бы лучше, чем Комитету, судить, какие реализации следует ожидать в каких моделях.
Исторически сложилось, что на большинстве платформ компиляторам ничего не стоило бы вести себя какхотя автоматические объекты были инициализированы каким-либо произвольным образом, который был бы слишком непротиворечивым, чтобы быть полезным для любого вида генератора случайных чисел, но недостаточно надежно предсказуемым, чтобы использовать его для любых других целей , за исключением случаев, когда любое возможное значение было быхорош как любой другой [например, потому что часто легче скопировать объект без учета того, имеет ли он полезное значение, может быть дешевле, чем избегать копирования его, если он не содержит его].На некоторых платформах, однако, единственный способ обеспечить компилятору такое поведение - это явная инициализация таких объектов сама.Авторы Стандарта не хотели требовать, чтобы компиляторы для таких платформ инициализировали объекты с фиктивными значениями, которые, вероятно, были бы перезаписаны программистом, и решили вместо этого потребовать от программистов , чей код должен быть совместим с такими платформами должен был бы гарантировать, что ничто не использовалось без инициализации.
С тех пор, однако, вещи развились в направлении худшего из обоих миров.Авторы Стандарта не предприняли никаких усилий, чтобы гарантировать, что реализации должны гарантировать, что автоматические объекты будут вести себя так, как будто они инициализируются с произвольными значениями, тогда как это принесет некоторую выгоду, как правило, с нулевой стоимостью, поскольку они не видели причин ожидать, что реализации что-либо сделаютостальное в таких ситуациях.Сегодня, однако, некоторые компиляторы будут использовать тот факт, что действие как неопределенное поведение, как оправдание для предположения, что ни одна программа никогда не получит входные данные, которые приведут к этому действию.Поскольку такие предположения обычно не очень полезны, они обычно не влияют на поведение программы.Представление о том, что все UB приводит к бессмысленному поведению, на которое вы, похоже, намекаете, проистекает из того факта, что реализация, использующая UB для вывода о том, что вещи не произойдут, когда они действительно происходят, склонна генерировать совершенно бессмысленный код втакие ситуации.Например, агрессивный оптимизатор может увидеть что-то вроде:
void test(int x)
{
int y,z;
if (x == 23)
y=z;
printf("%d\n",x);
}
и сделать вывод, что было бы «невозможно» вызвать функцию с любым значением x
, отличным от 23, и, следовательно, printfследует заменить на puts("23");
.Я не думаю, что какие-либо компиляторы вполне настолько агрессивны , но все же , но кажется модным рассматривать генерацию кода, который мог бы выводить другие значения x
, как "пропущенные"оптимизация».