Естественно, степень переносимости должна определяться исходя из реальных
условий. Нет такой вещи, как абсолютно переносимая программа, — разве только
программа, опробованная не во всех средах. Однако мы можем сделать
переносимость одной из своих главных целей, стараясь создать программу, которая
бы выполнялась без изменений практически везде. Даже если эта цель не будет
достигнута
в полном объеме, время, потраченное на ее достижение, с лихвой
окупится, если программу придется переделывать под другие условия.
Мы хотим посоветовать следующее: старайтесь писать программы, которые бы
работали при всех комбинациях различных стандартов, интерфейсов и сред, в
принципе подходящих для ее исполнения. Не старайтесь исправить каждую ошибку
переносимости, добавляя дополнительный
код, наоборот, адаптируйте программу
для работы при новых ограничениях. Используйте абстракцию и инкапсуляцию,
чтобы ограничить и контролировать те непереносимые фрагменты кода, без которых
не обойтись. Если ваш код сможет работать при всех ограничениях, а системные
различия в нем будут локализованы, он станет еще и более понятным.
Язык
Придерживайтесь стандарта. Первое, что необходимо для создания переносимого
кода, — это, конечно, использование языка высокого уровня, причем его стандарта,
если таковой определен. Двоичные коды переносятся плохо, исходный код —
несколько лучше. Однако и для него трудно, даже для стандартных языков, описать
точно, каким именно образом компилятор преобразует его в машинные инструкции.
Очень немногие
из распространенных языков представлены единственной
реализацией: обычно имеется множество производителей различных версий для
различных операционных систем, которые к тому же со временем изменяются.
Каждая версия будет обрабатывать ваш код по-своему.
Почему стандарт не является строгим описанием? Иногда стандарт неполон и не
описывает отдельных специфических случаев. Иногда он намеренно неконкретен:
например, тип cha r в С и C++ может иметь знак, а может и не иметь; он даже не
обязательно должен быть 8-битовым. Подобные детали оставлены на усмотрение
создателя компилятора; в этом есть свои плюсы: стимулируется появление новых
эффективных реализаций; снимаются ограничения, накладываемые на железо, но
жизнь программиста, конечно, несколько усложняется. Вообще, степень
проработанности
стандарта зависит от многих глобальных причин. И наконец,
нельзя забывать, что языки достаточно запутанны, а компиляторы весьма сложны; в
них могут быть неправильности интерпретации и ошибки реализации.
Иногда же языки вообще не стандартизованы. Официальный стандарт ANSI/ISO С
был принят в 1988 году, а стандарт ISO C++ ратифицирован только в 1998-м. На
момент написания этой
книги не все из распространенных компиляторов
поддерживают это официальное описание. Язык Java сравнительно молод, и его
стандарт можно ждать только через несколько лет. Вообще стандарт языка
разрабатывается только после того, как создаются несколько конфликтующих*
версий, которые надо унифицировать, а сам язык получает достаточно широкое
распространение, оправдывающее затраты на стандартизацию. А между тем
по-
прежнему надо писать программы и поддерживать в этих программах различные
среды исполнения.
Итак, несмотря на то что пщ знакомстве со справочными руководствами и
стандартами складывается впечатление жесткой спецификации языка, они никогда
не описывают язык полностью, и различные версии компиляторов могут создавать