Письма в редакцию
Иногда в PC Week/RE появляются статьи, которые по своей направленности напоминают материалы для программистов-практиков, публиковавшиеся в журнале “Монитор”, который, к сожалению, уже не издается. Думается, статьи эти мало волнуют читателей, лишь использующих продукты информационных технологий, но весьма интересны для тех, кто их производит.
Например, в PC Week/RE, № 37/96, с. 53 была опубликована статья Сергея Бобровского, тему которой можно выразить следующими словами: “Оптимизация приемов программирования с целью уменьшения числа ошибок в исходном коде”.
При обсуждении качества кодирования традиционно встает вопрос, какие семантические конструкции того или иного языка программирования способствуют совершению ошибки, а какие - нет. Например, есть масса приверженцев программирования без оператора goto. Некоторые на дух не переносят цикл while (или repeat, в зависимости от языка). А С. Бобровский предложил избавиться от оператора if.
На мой взгляд, все эти меры (если их когда-нибудь воплотят в жизнь) не дадут желаемого эффекта. Ошибки в программах вызываются единственной причиной - невнимательностью программиста. (Разумеется, здесь не берется в расчет случай, когда человек просто не знает, как должен работать тот или иной алгоритм.) Невнимательность, в свою очередь, проявляется в опечатках и недоделках (или переделках). Очевидно, что программист может равновероятно отвлечься как посреди оператора if, так и посреди switch (или case). Поэтому удаление из языка одного оператора в пользу другого ничего не даст. Более того, многие предлагаемые замены не касаются содержания, а меняют лишь протокольное название семантической структуры. Когда говорится об ущербности условного оператора if, возникает вопрос, а не относится ли то же самое к условному (по сути) оператору case.
Дело в том, что оператор case (и даже расширенный case, где условия альтернатив произвольные) может быть получен на основе “ненавистного” оператора if и препроцессора языка Си. И обратное тоже верно. От оператора if любой желающий может избавиться уже сегодня, используя вместо него case. Боюсь только, что ошибок от этого меньше не станет.
Другое средство в виде принудительного снижения вложенности операторов if, которое предлагает С. Бобровский как панацею от ошибок, приведет лишь к тому, что логические условия в оставшихся операторах пропорционально усложнятся. На мой же взгляд, лучше иметь дело с большим числом простых конструкций, нежели с малым числом сложных. Как говорится, разделяй и властвуй.
На самом деле приемы надежного кодирования известны уже давно и даже рассматривались в незабвенном “Мониторе”. Главное правило - сконцентрировать внимание программиста на небольшом участке кода с заведомо “прозрачной” структурой и законченной функциональностью. Достигается это довольно просто: любая задача представляется в виде иерархии более мелких подзадач, каждая из которых реализуется в виде отдельной процедуры длиной в 10 - 15 строк, умещающейся на одном экране. При таком подходе вероятность ошибки в каждой отдельной процедуре (и, следовательно, в их композиции) существенно снижается. И не важно, какие операторы применены внутри процедуры. Даже пресловутый goto, от которого бросает в дрожь всех семантиков, бывает к месту. Нет смысла заменять его надуманной комбинацией циклов с break и continue, в которых разобраться гораздо труднее. В свете вышесказанного, язык Java, уже лишившийся оператора goto, на мой взгляд, потерял вместе с ним гибкость и “потенциальную прозрачность”.
Следует также отметить, что ошибки часто появляются вовсе не в конструкциях из операторов языка программирования, а в формульной записи (например, при расчете индекса массива или аргумента функции). От таких ошибок изменение семантики языка уже совершенно точно не спасет. Здесь необходим строгий, встроенный в код на уровне компилятора контроль выполняемых операций на допустимость. В Java, например, в этих целях исключена работа с указателями. Разумеется, совсем убрать указатели проще, чем добавить инструмент для их контроля - нечто похожее на то, что появилось в современных отладчиках.
Подводя итог, хотелось бы отметить, что все подвергаемые критике операторы присутствуют в той или иной модификации в большинстве языков программирования, и это, несомненно, свидетельствует об их востребованности. Конечно, использовать их можно по-разному: излишне злоупотребляя или строго к месту. Но оптимальное сочетание всех средств языка позволяет сохранить его мощь без ущерба для надежности кода.
Станислав Короткий