Искусство программирования для Unix
Шрифт:
Распространение тестового комплекта позволяет сообществу пользователей проверить свои версии перед отправкой пожеланий группе разработчиков.
Поощряйте разработчиков к использованию широкого многообразия платформ в качестве настольных и тестовых машин, для того чтобы непрерывная проверка кода на предмет дефектов переносимости стала частью обычной разработки.
Хорошая практика, подкрепляющая уверенность в коде, заключается в поставке кода с тестовым комплектом, который используется разработчиком и который можно запустить с помощью команды
19.2.3.4. Выполняйте контроль ошибок в коде перед выпуском
Под "контролем ошибок" (sanity check) здесь подразумевается использование всех доступных инструментов, обладающих приемлемой способностью к обнаружению ошибок, которые человек склонен пропускать. Чем больше таких ошибок обнаружат данные инструменты, тем меньше пользователям и самому разработчику придется с ними бороться.
При написании программ на C/C++ с использованием GCC рекомендуется выполнять тестовую компиляцию с параметром -Wall и устранять все ошибки перед каждым выходом новой версии. Кроме того, стоит компилировать код всеми доступными компиляторами — разные компиляторы часто обнаруживают различные проблемы. В частности, скомпилируйте программу на машине с действительно 64-битовой архитектурой. Базовые типы данных могут изменяться на 64-битовых машинах, и поэтому в них часто обнаруживаются новые проблемы. Найдите систему Unix-поставщика и запустите утилиту lint для проверки программы.
Используйте инструменты, которые ищут утечки памяти и другие ошибки времени выполнения. Программы Electric Fence и Valgrind — хорошие инструменты, доступные в виде открытого исходного кода.
Для Python-проектов полезным инструментом проверки может оказаться программа PyChecker <http://sourceforge.net/projects/pychecker>. Она часто обнаруживает нетривиальные ошибки.
При написании программ на Perl проверять код следует с помощью ключа
19.2.3.5. Проверяйте орфографию в документации и README-файлах перед выпуском версии
Проверяйте грамотность документации, README-файлов и сообщений об ошибках в программе. Сырой код, т.е. код, который вызывает появление сообщений об ошибках при компиляции и имеет орфографические ошибки в текстах README-файлов и предупреждений, приводит пользователей к мысли, что проектирование данной программы также случайно и бессистемно.
19.2.3.6. Рекомендованные практические приемы переносимости кода C/C++
При написании программ на С используйте полные ANSI-функции. В частности, используйте прототипы функций, которые помогают выявить несовместимость между модулями. Старые компиляторы в стиле K&R — древняя история.
Не полагайтесь на специфические для некоторых компиляторов функции, такие как GCC-параметр
Необходимый для обеспечения переносимости код должен быть изолирован в отдельной области и отдельном наборе исходных файлов (например, в подкаталоге os). Компилятор, библиотека и интерфейсы операционной системы с проблемами переносимости должны быть абстрагированы в файлы данного каталога.
Уровень переносимости представляет собой библиотеку (или, возможно, просто набор макросов в заголовочных файлах), которая извлекает только части API-интерфейсов операционных систем, в которых нуждается разрабатываемая программа.
Уровни переносимости также упрощают приложения. Программы редко нуждаются в полной функциональности или более сложных системных вызовах, таких как mmap(2) или stat(2), а программисты часто конфигурируют такие сложные интерфейсы неверно. Уровень переносимости с абстрактными интерфейсами (например, функция с именем
Рекомендуется всегда писать уровень переносимости на основе функции, а не на основе платформы. Попытки создания отдельных уровней переносимости для каждой поддерживаемой платформы приводят к многочисленным проблемам обновления и обслуживания. "Платформа" всегда выбирается на основе по крайней мере двух параметров: компилятор и версия библиотеки/операционной системы. В некоторых случаях используются три фактора, как когда Linux-поставщики выбирают библиотеку С независимо от версии операционной системы. В случае с M– поставщиками, N– компиляторами и O– версиями операционных систем, количество платформ быстро превышает пределы досягаемости любых коллективов разработчиков, кроме крупнейших. С другой стороны, при использовании стандартов языков и систем, таких как ANSI и POSIX 1003.1, набор функций является относительно ограниченным.
Выбор уровня переносимости можно осуществлять либо по строкам кода, либо по компилированным файлам. Нет различий при выборе альтернативных строк кода на платформе или одного из нескольких различных файлов. Практическое правило заключается в том, чтобы перенести код переносимости для различных платформ в отдельные файлы, когда реализация значительно отличается (распределение общей памяти в Unix и Windows), и оставлять код переносимости в одном файле, когда различия минимальны (например, в зависимости от использования функции
За пределами уровня переносимости необходимо придерживаться следующей рекомендации.
Директивы
Использование директив