Kernighan, B. W. and Ritchie, D. M. "The 'C' Programming Language"; Chapter 21
21. Строки управления компилятором.
Компилятор языка "C" содержит препроцессор, который позволяетосуществлять макроподстановки, условную компиляцию и включениеименованных файлов. Строки, начинающиеся с #, общаются с этимпрепроцессором. Синтаксис этих строк не связан с остальным языком;они могут появляться в любом месте и их влияние распространяется(независимо от области действия) до конца исходного программного файла.
Содержание
- 21.1. Замена лексем.
- 21.2. Включение файлов
- 21.3. Условная компиляция.
- 21.4. Управляющая строка - line.
- 21.2. Включение файлов
21.1. Замена лексем.
Управляющая компилятором строка вида
#define идентификатор строка-лексем(обратите внимание на отсутствие в конце точки с запятой) приводитк тому, что препроцессор заменяет последующие вхождения этогоидентификатора на указанную строку лексем. Строка вида
#define идентификатор (идентификатор,...,идентификатор) строка лексемгде между первым идентификатором и открывающейся скобкой ( нет пробела,представляет собой макроопределение с аргументами. Последующеевхождение первого идентификатора, за которым следует открывающая скобка'(', последовательность разделенных запятыми лексем и закрывающая скобка')', заменяются строкой лексем из определения. Каждое вхождениеидентификатора, упомянутого в списке формальных параметров в определении, заменяется соответствующей строкой лексем из обращения. Фактическимиаргументами в обращении являются строки лексем, разделенные запятыми;однако запятые, входящие в закавыченные строки или заключенные в круглыескобки, не разделяют аргументов. Количество формальных и фактическихпараметров должно совпадать. Текст внутри строки или символьнойконстанты не подлежит замене.
В обоих случаях замененная строка просматривается снова с цельюобнаружения других определенных идентификаторов. В обоих случаяхслишком длинная строка определения может быть продолжена на другойстроке, если поместить в конце продолжаемой строки обратнуюкосую черту \.
Описываемая возможность особенно полезна для определения"об'являемых констант", как, например,
#define tabsize 100 int table[tabsize];Управляющая строка вида
#undef идентификаторприводит к отмене препроцессорного определения данного идентификатора.
21.2. Включение файлов
Строка управления компилятором вида
#include "filename"приводит к замене этой строки на все содержимое файла с именемfilename. Файл с этим именем сначала ищется в справочнике начальногоисходного файла, а затем в последовательности стандартных мест. Вотличие от этого управляющая строка вида
#include <filename>ищет файл только в стандартных местах и не просматривает справочникисходного файла.
Строки #include могут быть вложенными.
21.3. Условная компиляция.
Строка управления компилятором вида
#if константное выражениепроверяет, отлично ли от нуля значение константного выражения (см. п. 24). Управляющая строка вида
#ifdef идентификаторпроверяет, определен ли этот идентификатор в настоящий момент впрепроцессоре, т.е. определен ли этот идентификатор с помощьюуправляющей строки #define. Управляющая строка вида
#ifndef идентификаторпроверяет, является ли этот идентификатор в данный момент неопределенным для препроцессора.
За каждым из трех перечисленных видов строк может следоватьпроизвольное число строк, возможно содержащих управляющую строку
#elseи затем управляющая строка
#endifЕсли проверяемое условие истинно, то любые строки между #else и#endif игнорируются. Если проверяемое условие ложно, то любые строкимежду проверяемой строкой и #else или, при отсутствии #else, #endifигнорируются.
Эти конструкции могут быть вложенными.
21.4. Управляющая строка - line.
Для других препроцессоров, генерирующих "C"-программы, используетсястрока вида
#line константа идентификаторкоторая приводит к тому, что компилятор в целях диагностики ошибокполагает, что следующая строка исходного файла имеет номер,задаваемый константой, и что текущий входной файл именуется этимидентификатором. Если идентификатор отсутствует, то запоминаемоеимя файла не изменяется.