Первоначально большинство форм неопределенного поведения представляли собой вещи, которые некоторые реализации могут ловушки, но другие реализации могут и не быть. Поскольку авторы Стандарта не могли предсказать все, что платформа могла бы сделать в случае ловушки (включая, в буквальном смысле, возможность того, что система выдаст сигнал тревоги и заблокируется до тех пор, пока оператор не устранит неисправность вручную) , последствия ловушек выходят за рамки юрисдикции Стандарта С, и, таким образом, почти все действия, для которых какая-то платформа может вызвать ловушку, - с точки зрения Стандарта - считается «Неопределенным поведением».
Не следует принимать во внимание, что авторы Стандарта не полагали, что реализации должны стараться вести себя разумно для таких вещей, когда это практично.Авторы C89 стандарта отметил, что, например, большинство существующих систем той эпохи будут определять поведение для:
/* Assume USmall is half the size of "int" */
unsigned mult(USmall x, USmall y) { return x*y; }
которая во всех случаях, в том числе тех, где математическое произведение х и у было между INT_MAX + 1 и UINT_MAX, эквивалентны (unsigned)x*y;
. Я не вижу причин полагать, что они не ожидали продолжения этой тенденции.
К сожалению, новая философия стала модной, основанной на ревизионистской точке зрения, что авторы-компиляторы поддерживали только полезное поведение в случаях, не предусмотренных Стандартом, потому что они были слишком неискушенными, чтобы делать что-либо еще. Например, в gcc, используя уровень оптимизации 2, но без других параметров, отличных от параметров по умолчанию, вышеупомянутая процедура «mult» иногда генерирует фиктивный код в случаях, когда продукт будет находиться между 0x80000000u и 0xFFFFFFFFu, даже если он работает на платформах, где такие вычисления будут исторически работали. Предполагается, что это делается во имя «оптимизации»; было бы интересно узнать, сколько из «оптимизаций» таких методов в конечном итоге выполняют действительно полезны и не могли быть достигнуты с помощью более безопасных средств.
Исторически Неопределенное Поведение было лицензией для компилятора С, чтобы выявить поведение базовой платформы; в случаях, когда поведение базовой платформы соответствует потребностям программиста, это позволило повысить требования программиста к машинным кодам более эффективно, чем если бы все было сделано способами, определенными Стандартом. Однако в последнее время это интерпретируется как лицензия для компиляторов на внедрение поведения, которое не только не имеет никакого отношения ни к чему в базовой платформе, ни к каким-либо вероятным ожиданиям программистов, но даже не связано законами времени и причинности.
Вы имеете в виду, кроме очевидной причины? –
Существует штраф за выполнение при проверке границ каждого доступа к одному массиву. –
, потому что это довольно трудно запретить, по крайней мере, в прошлом и сейчас. – user3528438