CPP(1) CPP(1) НАЗВАНИЕ cpp - препроцессор для языка C СИНТАКСИС |LIBDIR/cpp [-P] [-C] [-U имя] [-D имя[=значение]] [-T] [-I каталог] | [-Y каталог] [-H] [входной_файл [выходной_файл]] ОПИСАНИЕ Cpp - это препроцессор языка C, который вызывается в качестве первого прохода при любой компиляции C-прог- рамм командой cc(1). Формат результатов работы cpp поз- воляет использовать их в качестве исходных данных для следующего прохода C-компилятора. Поскольку язык C раз- вивается, cpp и остальные команды пакета C-компиляции будут модифицироваться, чтобы следовать изменениям язы- ка. Поэтому использование команды cpp, минуя cc(1), чревато неприятностями: в один прекрасный день cpp мо- жет заработать совсем иначе. См. также m4(1) - универ- сальный макропроцессор. При вызове cpp в качестве аргументов могут быть указаны два имени файла - входной_файл и выходной_файл препро- цессора. По умолчанию вместо них используются стандарт- ный ввод и стандартный вывод. Опции: -P Препроцессировать входной файл без генерации уп- равляющей информации о номерах строк, используемой следующими проходами C-компилятора. -C Копировать в выходной файл все комментарии за иск- лючением комментариев в директивах cpp. По умолча- нию cpp подавляет C-языковые комментарии. -U имя Удалить начальное определение зарезервированного имени. Перечень таких имен зависит от конкретного препроцессора. Текущий перечень (он разбит на группы, отвечающие смыслу зарезервированных имен): операционная система: unix, dmert, gcos, ibm, os, tss аппаратура: interdata, pdp11, u370, u3b, u3b5, u3b2, u3b20d, vax, m68k вариант системы UNIX: RES, RT утилита lint(1): lint -D имя -D имя[=значение] Определить имя; действие эквивалентно директиве #define. Если =значение не указано, имя определя- ется как 1. Опция -D имеет более низкий приоритет, чем -U. Это означает, что если одно и то же имя встретилось в обеих опциях, оно окажется неопреде ленным, независимо от порядка перечисления опций. -T Длина имен в препроцессоре теперь не ограничена восемью символами (исключение - PDP-11). Если же задана опция -T, значимыми считаются только первые восемь символов. Предыдущие версии препроцессора поступали с длинными именами так же; в текущую версию данная опция включена для совместимости "назад". -I каталог Изменить алгоритм поиска включаемых файлов по ди- рективе #include: файлы, имена которых начинаются не с /, перед поиском в каталогах из стандартного списка искать в указанном каталоге. При использо- вании данной опции включаемые файлы, имена которых заключены в кавычки, сначала ищутся в том катало- ге, где находится аргумент входной_файл, затем в каталогах, указанных в опции, и в последнюю оче- редь в каталогах из стандартного списка. Для вклю- чаемых файлов, имена которых заключены в <>, поиск в каталоге с входным_файлом не производится. -Y каталог При поиске включаемых файлов использовать указан- ный каталог вместо каталогов из стандартного спис- ка. -H Выдавать в стандартный протокол, по одному в стро- ке, составные имена включаемых файлов. Выделено два специальных имени. Имя __LINE__ определено как номер текущей строки с точки зрения cpp (десятичное целое число), __FILE__ - имя текущего файла (C-цепочка символов). Данные имена могут использоваться всюду (включая макросы) как и другие имена, получившие опре деления. Все директивы cpp начинаются со строк, первым символом в которых является #. Между # и собственно директивой допускается любое число пробелов и символов табуляции. Имеются следующие директивы: #define имя цепочка_лексем Заменить последующие вхождения имени на цепочку_- лексем. #define имя( арг, ..., арг ) цепочка_лексем Заменить последующие вхождения конструкций, состо ящих из имени, открывающей скобки, списка разде ленных запятыми лексем и закрывающей скобки, це- почкой_лексем, в которой каждое вхождение арг за- менено соответствующей лексемой из списка. Заме тим, что пробелов между именем и открывающей скоб- кой быть не должно. После того, как выполнена подстановка цепочки_лексем, cpp вновь просматрива- ет ее в поисках имен, подлежащих макроподстановке. #undef имя Забыть с данного момента определение имени (если оно имелось). После имени запрещается располагать другие лексемы. #ident "цепочка_символов" Поместить цепочку_символов в секцию комментариев объектного файла. #include "файл" #include <файл> Вставить в данное место содержимое файла (которое будет затем обработано cpp). Если используется за- пись <файл>, файл ищется только в стандартных ка- талогах. Дополнительную информацию см. выше в опи сании опций -I и -Y. После закрывающих символов " и > запрещается располагать другие лексемы. #line целая_константа "файл" Сформировать управляющую информацию для следующего прохода C-компилятора. Целая_константа - это но- мер, который получает следующая строка, файл - приписываемое строке имя файла. Если "файл" не задан, текущее имя файла не изменяется. После нео- бязательного аргумента файл запрещается распола- гать другие лексемы. #endif Завершает группу строк, которая начата условной директивой (#if, #ifdef или #ifndef). Каждой ус- ловной директиве должна соответствовать директива #endif. После #endif запрещается располагать дру- гие лексемы. #ifdef имя Следующие строки копируются в выходной файл, если имя в настоящий момент определено. После имени запрещается располагать другие лексемы. #ifndef имя Следующие строки не копируются в выходной файл, если имя в настоящий момент определено. После име- ни запрещается располагать другие лексемы. #if константное_выражение Следующие строки копируются в выходной файл, если значение константного_выражения не равно 0. В констант- ном_выражении допустимы все бинарные операции языка C (кроме присваивания), операция ?:, унарные операции -, ! и ~. Приоритеты операций такие же, что и в C. Определена еще одна унарная операция, которая может использоваться в констант- ном_выражении в двух формах: defined(имя) или defined имя. Благодаря этой операции #ifdef и #ifndef являются частными случаями директивы #if. В константном_выражении могут быть использованы только эти операции, целочисленные константы и имена, которые известны cpp. В частности, недопус- тима операция sizeof. Чтобы проверить, определено ли хотя бы одно из двух имен, foo и fum, следует воспользоваться ди- рективой |#if defined(foo) || defined(fum) #elif константное_выражение Допускается произвольное число директив #elif меж- ду #if, #ifdef, #ifndef с одной стороны и #else или #endif с другой. Следующие после #elif строк копируются в выходной файл, если проверка пред- шествующих условий дала результат "ложь" (0), а значение константного_выражения оказалось отличным от нуля. В этом случае последующие директивы #elif и #else игнорируются. После #elif допускаются те же константные_выражения, что и после #if. #else Следующие после #else строки копируются в выходной файл, если проверка предшествующих условий дала результат "ложь" (0). После #else запрещается рас- полагать другие лексемы. Условные директивы и необязательные директивы #else мо- гут быть вложены. ФАЙЛЫ INCDIR Стандартный список каталогов для поиска включаемых файлов, обычно /usr/include. LIBDIR Обычно это /lib. СМ. ТАКЖЕ cc(1), lint(1), m4(1). ДИАГНОСТИКА Сообщения об ошибках, формируемые cpp, не нуждаются в пояснениях. Вместе с диагностикой печатаются номер строки и имя файла, где встретилась ошибка. ПРИМЕЧАНИЯ Когда в списке аргументов раскрываемых макроопределений встречались символы перевода строки, предыдущие версии cpp, раскрывая макроопределения, эти символы подставля- ли. Текущая версия cpp заменяет символы перевода строки на пробелы, чтобы смягчить проблемы, с которыми сталки вались предыдущие версии. Неподдерживаемая опция -W позволяет использовать дирек тивы #class. Если такая директива встретилась в файле, cpp, выполнив другие директивы, завершается с кодом 27. Опция задумана для реализации классов в языке C. Поскольку в разных окружениях стандартные каталоги для включаемых файлов могут быть различными, директиву |#include следует предпочесть явному указанию полного имени: |#include "/usr/include/file.h" В случае использования полных имен cpp выдает предуп- реждения.