Первые тестовые прогоны были кошмарны: на половине тестов компилятор выдавалвереницы жутких диагностических сообщений, которые, казалось, никогда не должныпоявляться, другие аварийно заканчивались знаменитой диагностикой "coredumped", те тесты, которым все-таки удалось прорваться сквозь компилятор, приисполнении выдавали неверные результаты, и лишь единицы завершались скромнойфразой "test passed". Казалось, не в силах человеческих разобраться в этойкаше. Однако, капля камень точит.
Поначалу-то как раз было легче — в первую очередь находились и исправлялисьочевидные ляпы. Как правило, одно исправление приводило к проталкиваниюдесятка, а то и больше ранее неудачных тестов. Были, конечно, и "наведенные"ошибки, которые в один прекрасный день магическим образом бесследно исчезали,оставляя после себя смутное беспокойство (а вдруг, как исчезли, так и вновьпоявятся?). Но чем дальше двигалась отладка, тем дороже давался каждый тест.Ошибки становились все тоньше, специфичнее и тяжелее в поиске, а чтобыисправить найденную ошибку, иногда приходилось перетрясти десяток функций вразных модулях. Исправление одной ошибки не раз приводило к появлению целойсерии "экранированных" ею ошибок, которые не могли проявиться до ликвидациипервой ошибки. Компилятор, казалось, сопротивлялся лечению, словно строптивыйребенок.
А тут еще в самый разгар работы, когда ошибки щелкаются одна за другой,компилятор на глазах выздоравливает, словно от тяжелой болезни,-- приходит новаяверсия стандарта. Значит, надо опять смотреть, что изменилось. Ладно есливводится новая языковая возможность, это может быть несложно в реализации идаже приятно: когда ни у Borland, ни у gcc еще не были реализованы описательmutable или булевский тип, у нас уже все работало. Хуже, если уточняютсядетали семантики хорошо известных конструкций, что, как правило, влечет засобой переделку базовых алгоритмов. Так, общий алгоритм сравнения типов,алгоритм обработки совместно используемых функций (одноименных функций,различающихся числом и типами параметров) и в особенности, алгоритмы,реализующие правила вызова деструкторов и обработки исключений переделывалисьпосле почти каждой новой версии предварительного стандарта. Понятно, что каждаятакая переделка работающей программы вызывает поток новых ошибок, и мыоткатываемся на месяц назад…
Вдобавок, изменяются сами тесты. Тестовый набор растет, охватывает все новыесферы языка, студенты становятся все искушеннее и опытнее, их тесты всеизощреннее, да и мы постоянно находим в тестах ошибки, которые также становятсявсе тоньше и незаметнее. Не только компилятор отлаживается на тестах, но итестовый набор отлаживается на компиляторе.
А интересно, как тестирует свои компиляторы Watcom?
Быстро сказка сказывается, да не скоро дело делается
Примерно через год после начала работы, как и следовало ожидать, мы осозналиабсолютную нереальность и даже абсурдность первоначального срока. Хотя к этомувремени у нас уже был сделан Проект, реализовано большинство базовыхалгоритмов, программа (ее, конечно, еще нельзя было назвать компилятором) какединое целое уже начинала шевелиться, настоящее понимание языка Си++ итого, как следует делать компилятор с него, только-только появлялось. Мыпоняли, что работа только начинается.
Те, кто успел поработать в советских научно-исследовательских организациях,хорошо знают цену так называемым эскизным проектам. При его составлениинастоящего понимания того, как, собственно, следует разрабатывать иреализовывать программную систему, ни у кого нет. Основная цель заключается втом, чтобы "застолбить" работу, успокоить начальство и открыть финансирование.Если речь идет о действительно новой работе, опыта выполнения которой у авторовпроекта нет, то он содержит либо общие слова и красивые схемы, либо более илименее аккуратные и тщательно продуманные предположения, опять-таки выраженные вдостаточно обобщенных категориях. После сдачи эскизного проекта его, какправило, прочно забывают и разрабатывают систему так, как это подсказывают опыти квалификация.
Наш проект, который мы через несколько месяцев представили бельгийцам, былразработан гораздо серьезнее, однако сам предмет оказался настолько сложен, чтостепень проработки проблем оказалась недостаточной. Время от времениприходилось возвращаться к проекту и вносить в него изменения и добавления. Содной стороны, это замедляло работу по реализации и не всем нравилось (выше яуже писал об этом). С другой — время разработки проекта даже очень сложнойсистемы не должно быть чрезмерно большим: многого просто невозможно предвидеть — парадокс в том, что только начав реализацию, можно получить обоснованныепроектные решения. К тому же программистам психологически очень тяжело неделии месяцы проводить в обсуждениях, рисовать схемы и писать тексты (между прочим,на английском языке!-- в контракте специально был оговорен proper English), несоставив ни строчки кода (здесь мы хорошо понимаем третьего участника). Но дажеесли бы подобных задержек не было, мы физически не успели бы запрограммироватькомпилятор, оставаясь в пределах заявленного срока — объем программного текста,который предстояло написать, во много раз превышал то, что уже было написано. Онекоторых трудностях реализации, которые ждут нас впереди, было даже страшнозадумываться.
К нашему удивлению, бельгийцы легко согласились с продлением срока работы.Впрочем, они довольно плотно (хотя до времени и формально) контролировали весьпроцесс и могли понять, что мы даром времени не теряем и перенос сроков носитобъективный характер.
Дальше начинается психология. Вообще говоря, первоначальные сроки никто никомуне навязывал: предложили их мы, но они-то согласились! Поэтому, казалось бы,ответственность за тот факт, что эти сроки оказались нереальными (кажется, иони, и мы сейчас это понимали), следовало бы разделить между всеми. Однакокомплекс вины чувствовали именно мы (они, как в личном общении, так и вписьмах, вообще проявляли мало эмоций и крайне редко допускали неформальныйстиль общения). И хотя теперь-то мы могли предложить более обоснованные иреалистичные сроки завершения проекта, этот комплекс нам, к несчастью, помешал.
К тому времени мы уже вполне убедились, что квалификация позволяет нам надостойном уровне довести проект до завершения без чьей бы то ни было помощи.Наши консультации с заказчиками сводились к вопросам о конкретном устройстветех компонент их системы программирования, с которыми компилятор долженвзаимодействовать. Даже на вопросы о формате промежуточного представления,которое, согласно фирменной документации, было их собственной разработкой, онидалеко не всегда могли дать вразумительный ответ (позднее это нашло своеобъяснение). Обсуждать детали языка было не с кем, собственных специалистов поСи++ у них не было, они вообще до сих пор программировали на Си самойдревней версии Кернигана и Ритчи. Их помощь состояла в периодических посылкахочередных версий предварительного стандарта (до тех пор, пока рабочая группа нестала выкладывать их на свой Web-сервер) и материалов очередных заседаний идискуссий, предшествующих принятию того или иного языкового свойства. Последнеебыло действительно интересно и ценно, так как эти материалы, насколько мызнаем, нигде не публикуются и рассылаются только членам рабочих групп.
В общем, мы вполне могли бы чувствовать себя полноправными партнерами фирмы.Однако, несмотря на все сказанное, мы еще долгое время не могли избавиться отощущения учеников или, по крайней мере, подмастерьев в мастерской именитогохудожника. И то, что мы не успевали вовремя выполнить работу, осознавалось намикак непростительная оплошность новичка, не поспевшего загрунтовать холст кприходу мэтра. К этому добавлялась не имеющая совершенно никаких основанийбоязнь, что, услышав просьбы о пересмотре сроков, фирма прекратитсотрудничество с нами.