скрещенными костями в комментариях, где говорилось примерно следующее: “Здесь очень запутанный код”. То был кусок в самой глубине поискового кода, или чего-то такого, и он был заоптимизирован до смерти. Исключительно сложный для понимания код. Как черный ящик с надписью “Не влезай, если не уверен”.
Но если поглядеть на программы, которые мы пишем сегодня, через призму моего опыта, они гораздо больше, уродливее и к тому же медленнее. И это нормально. Сейчас подобные вещи уже не имеют значения. Ребята, которые делают сегодня программы для сведения видео или для компьютерной анимации, просто не могут позволить себе такую роскошь. Для этого требуется много очень аккуратного программирования. Я уже не могу делать такие вещи. Но когда-то это было мне по силам. И я понимаю нынешних программистов. Большая часть программирования сегодня - рутина.
В одном колледже курс программирования длился два семестра, с сентября по май, и уже в самом начале студент должен был составить довольно трудную программу. Но он не подозревал, что в апреле ему придется делать это снова, причем на этот раз к его работе будут предъявлены гораздо более жесткие требования. Идея была в том, чтобы студент понял, насколько трудно вспомнить вещи, о которых полгода назад думал, что хорошо их понимаешь.
Сейбел: То есть все, что ты когда-то лихорадочно делал в последнюю ночь, возвращается к тебе во всей красе.
Козелл: Совершенно верно. По-моему, прекрасная схема. Отлично готовит к трудностям реальной жизни.
Сейбел: Беседуя с Кеном Томпсоном, я спросил его, есть ли у языка Си врожденные пороки, которые привели к проблемам с безопасностью. И он сказал, что на самом деле все было в порядке. Преподавая компьютерную безопасность, как вы прокомментируете это?
Козелл: Не хотел бы скрещивать с ним шпаги, но в своем курсе говорю, что самые большие проблемы с безопасностью у современных компьютеров бывают как раз из-за Си. Он был создан как язык системного программирования и оказался таким удачным, что его стали использовали во всех важных проектах. Мы пишем на нем операционные системы и системы реального времени.
Я помню, какие войны кипели в эпоху Паскаля. Говорилось, что компьютер должен сам помогать тебе; что Си слишком опасен как язык программирования. Помнится, эту позицию отстаивали два авторитета - Вирт и Дейкстра. По другую сторону баррикад находились все известные мне системные программисты, включая меня самого. Я писал все на Си. Этот язык, можно сказать, смел тогда всех конкурентов.
Правительство пыталось поддержать Аду, заключая контракты только на написание программ на Аде. Си пробил и эту стену. Он был просто великолепен. Но и сегодня я не перестаю удивляться тому, что в Си невозможно написать сколько-нибудь сложную программу, не столкнувшись при этом с проблемой безопасности. Этот язык требует от программиста много возни: необходимо каждый раз при копировании информации в буфер тщательно проверять, не выйдет ли она за его пределы; следить, чтобы ни в коем случае не стереть информацию из памяти не вовремя, чтобы указатель где-то в программе не стал неактуальным; следить за тем, чтобы не сохранить что-то, имеющее неправильный размер и способное затереть следующую переменную; эти проблемы нелегко бывает выявить впоследствии.
Но когда-то это было просто спасение для системных программистов. От мысли о том, что мы могли бы писать системы на ассемблере, а приложения - на Паскале, у меня мурашки по спине бегут. Не думаю, что это было бы правильно. Но имея опыт написания как систем, так и приложений на Си, должен сказать, что этот язык не оправдал наших ожиданий. Работать в нем оказалось слишком сложно.
Пример тому - ошибки в программах с прерываниями. Вы можете сказать, что в написании программ с прерываниями ничего сложного. И это действительно так. Нужно всего лишь немного понимания и немного старания. Но я знаю случаи, когда по-настоящему хорошие программисты, обладающие и тем, и другим, делали ошибки в своих программах. Таким, как я, приходилось исправлять эти ошибки, и в конце концов я написал язык в стиле Никлауса Вирта, не дающий программистам ошибиться при работе с прерываниями.
Для системы IMP я написал сложный набор ассемблерных макросов, позволявших объявлять, что делаешь. Дойдя до прерывания, пишешь объявление вроде: “Я обрабатываю данные из модема” или “Я в высокоприоритетном или низкоприоритетном таймере”. И когда программа ассемблируется, для каждой инструкции проставляется метка и на каком уровне прерывания она выполняется, а затем запускается постпроцессор, написанный мною, кажется, на макросах ТЕСО, и проверяет, нет ли проблем с разделением времени. Если он обнаруживает переменную, доступ к которой осуществляется из двух разных уровней, то пишет: “Обнаружен конфликт прерываний”. И ошибка с разделением времени сама собой исправляется. Программист быстро привыкает к тому, что если он пишет правильные объявления, система сама удерживает его от ошибок. Я специально ездил в Венгрию, чтобы показать, как не разбирающиеся в проблемах разделения времени программисты могут с помощью этого метода писать соответствующие программы на хорошем уровне.
Вот, если вкратце, что я думаю о Си. Уверен, что есть хорошие программисты, возможно, и я в их числе, которые могут писать на этом языке хорошие программы. Но это дается нам труднее, чем должно было быть. В современном мире эта проблема усугубилась, потому что вокруг становится все больше и больше программ на Си, и у программистов все больше работы по преодолению их недостатков. Это одна из причин, по которым мне нравится программировать на Perl. Perl медленный. Думаю, это один из самых медленных языков программирования, но зато в нем нет тех проблем с безопасностью, которые есть в Си. Что происходит в Perl, если информация не влезает в массив? Массив увеличивается в размерах, только и всего.
Этот язык знает, куда указывают его указатели, так что вы никогда не сможете “сбиться с пути”: нужно просто сказать системе, чтобы проследила путь и узнала, куда он ведет. Я уверен в этом языке, потому что на протяжении многих лет люди работают с его ядром, и оно очень стабильно. Не думаю, что в написанных на нем программах попадается много ошибок выделения памяти или проблем с указателями; фактически их вообще трудно допустить в коде Perl. He приходится надеяться только на программистов.
И даже после этого бывают случаи вроде того хрестоматийного, когда кто-то написал веб-страницу, искавшую имена в таблицах, а неизвестный хакер написал в строке ввода что-то вроде “Joe;drop all tables”. Такое еще случается. Это, конечно, не вина языка Си, но видно, что программисты подчас бывают недостаточно осторожны. Они не продумывают все варианты, а в Си их слишком много. Все это кажется мне слишком опасным. Справедливости ради нужно добавить, что я программировал на Си на пять лет меньше Кена. Мы с ним в разных весовых категориях, но все же у меня большой опыт общения с Си, я знаю, как это непросто, и думаю, что дело тут, по большей части, в самом языке.
По мере того как приложения будут становиться все более и более сложными, построенными на все более и более сложных библиотеках, - и все окончательно перестанут понимать, где в них “дыры” из-за их чрезвычайной сложности, - наверное, нам придется перейти к программированию приложений на менее располагающем к ошибкам языке. Процессоры становятся потрясающе быстрыми, а память - удивительно дешевой. Не могу сказать, какой он - завтрашний язык программирования. Не думаю, что Си или его дальнейшие модификации, вроде C++, станут подходящей платформой, на которой программирование приложений - даже развитие систем - сможет двигаться дальше.
Java не кажется мне выходом. Мои старые рефлексы не подводят. Этот язык неприятно поразил меня своей авторитарностью. Это еще одна причина, по которой я хвалю Perl, - он безопасный, надежный и при этом чертовски разнообразный, так что художник во мне получает достаточное поле для самовыражения и выбора оптимальных путей. Я свободен.
Впервые попробовав Java - еще совсем молодой тогда язык, - я сказал себе: “А, еще один язык, призванный помочь посредственным программистам встать на путь истинный, ограничивая их”. Но, возможно, сейчас это и правильно. Пожалуй, сегодня опасно полагаться на хороший, гибкий язык, на котором один или два процента программистов смогут писать высокохудожественные программы, потому что в мире уже 75 миллионов штампованных программистов, пишущих чрезвычайно сложные приложения и нуждающихся в помощи. Так что, вероятно, Java - это то, что нужно. Я не знаю.
Сейбел: До вас я брал интервью у Фрэн Аллен, сотрудницы IBM, писавшей компиляторы для Фортрана. Её Си разочаровал совсем другим - тем, что для него невозможно написать