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 выдает предупреждения.