| Наука — Школе | 
В старых языках программирования (фортран и т.п.) при обращении к 
элементам массива компилятор, как правило, не предусматривает проверок, выходит 
ли индекс за границы массива. В другом старом языке — C, 
где с массивами можно работать с помощью указателей — подобные проверки вообще 
могут быть невозможны. В таких условиях, если происходит ошибочное обращение к 
несуществующим элементам массива, то программа просто считывает содержимое ячеек 
памяти, никакого отношения к данному массиву не имеющих, либо записывает туда 
какую-то информацию, портя содержимое других переменных, возможно, в других 
программах, и затем продолжает свою работу, уже скорее всего бессмыссленную. 
В конце концов либо 
выдается невнятный результат, либо программа аварийно останавливается в какой-то 
точке, не имеющей никакого отношения к ошибке. Либо что-то неожиданное происходит с другими 
программами на компьютере. 
Понятно, что искать ошибку такого рода отнюдь не 
легко — ведь при каждом новом вызове программа может загружаться в разные 
области памяти и, соответственно, ошибочно обращаться к разным областям памяти.
Когда было обнаружено, насколько велика доля ошибок, связаных с выходом за границы массивов, в компиляторы стали добавлять возможность включать в код проверку индексов на предмет выхода за границы массива. Но это обычно делается, только если компилятор работает в специальном «отладочном» режиме. Разумеется, «настоящий» программист считает отладочный режим средством для новичков-«чайников».
Оберон/Компонентный Паскаль не предусматривает никакого специального отладочного режима, а проверки индексов на предмет выхода за границы массива отключить просто нельзя. В результате «настоящий» программист чувствует, что ему навязана роль «чайника», и выдвигает следующиее «практическое» возражение: дескать, включение таких проверок увеличивает и замедляет скомпилированную программу.
На самом деле экспериментальное изучение программ доказывает, что и 
тот и другой эффект в подавляющем большинстве случаев ничтожен (при условии 
тщательного дизайна языка и компилятора, как это имеет место для 
Оберона/Компонентного Паскаля). 
Жертвовать же надежностью всех программ 
ради ускорения пусть даже на десяток процентов в  редком случае —  безответственно 
(гораздо чаще имеет место замедление на уровне 1%, если его вообще удается 
достоверно измерить). 
Если же такая редкая программа предназначена для частого 
использования, то и оптимизировать ее нужно особыми методами, например, 
переписав соответствующий фрагмент непосредственно в машинных кодах (цикл, в 
котором проверка индексов заметно сказывается на производительности, вряд ли 
будет сложным, так что написать несколько команд в машинных кодах  труда не 
составит для специалистов, которые обычно занимаются такими программами; о 
том, как включать фрагменты в машинных кодах непосредственно в программу на 
Компонентном Паскале, см. в документации Блэкбокса 
Platform-Specific Issues, раздел Code 
procedures).
Возможно и возражение метафизическое, мол, ограничения такого рода (как и исключение
оператора GOTO, 
и т.п.), навязываемые «профессионалу», ограничивают его свободу творчества. Но 
во-первых, величина и сложность подавляющего большинства полезных программ 
оставляет достаточный простор для творчества и за вычетом мелкой возни с 
индексами массивов. 
Во-вторых, программирование — сколько бы ни было в нем от 
искусства — это прежде всего эффективное создание правильных, надежных и 
эффективных программ (эффективность не имеет 
смысла, если программа неправильная или приводит к  взрыву ракеты или потере 
финансовой отчетности). 
Посмотрим с этой точки зрения на вариант ошибки такого рода из числа наихудших — а именно, на ситуацию, когда данные, записываемые в массив, поступают из Интернета. В таком случае, если программа не проверяет выход за границу буфера — массива, предназначенного для записи приходящей из Интернета информации, — можно заставить программу записать в какую-то область памяти исполняемый код и даже передать ему управление, тем самым перехватив управление компьютером. Именно в этом состоит излюбленный хакерами способ проникать в компьютеры, подключенные к Интернету — атака посредством переполнения буфера (buffer overflow).
Сообщениями о таких атаках пестрят новостные ленты компьютерного мира. Например, вспомним одну поучительную историю. В августе 2001 г. вице-президент Майкрософт Джим Олчин (Jim Allchin) объявил во время доклада на открытии конференции Intel Developers Forum в Сан Хосе, что в новой операционной системе Windows XP все возможные проблемы из разряда переполнение буфера были устранены посредством специального анализа исходных текстов на предмет безопасности (security audit). Но в декабре того же года была найдена «дыра» в одной из программ в составе Windows XP (в программах поддержки стандарта подключения внешних устройств Universal Plug and Play) — причем дыра оказалась именно из категории переполнение буфера.
Вопрос: Почему аудит исходных текстов, о котором объявил 
Джим Олчин, не обнаружил этой проблемы? 
Ответ: Потому что вовсе не равна нулю вероятность ошибиться живым 
людям, выполнявшим аудит 50 миллионов строк программ на нечитабельном языке типа
C.
В начале 2002 г. Майкрософт на месяц приостановила нормальную работу, чтобы программистский персонал мог специально сосредоточиться на проблемах безопасности и надежности программ. Если оценить количество программистов Майкрософт в 20 тысяч человек при зарплате от $150 тыс. в год и выше, то стоимость месячника повышения квалификации выйдет не меньше 250 миллионов долларов. Майкрософт в состоянии это себе позволить. Остальным, видимо, все же дешевле перейти на инструменты программирования, где проверки индексов массивов не отключаются. Впрочем, и сама компания Майкрософт в настоящее время переходит на платформу .NET, в которой главный язык программирования — т.наз. C# — смоделирован во многом, в том числе и в отношении безопасности программирования, по образцу Оберона.
| Наука — Школе |