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 <file.h>
следует предпочесть явному указанию полного имени:
#include "/usr/include/file.h"
В случае использования полных имен cpp выдает предупреждения.