Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Справочник по С++.doc
Скачиваний:
49
Добавлен:
02.05.2014
Размер:
995.33 Кб
Скачать

R.16.3.1 Операция #

Если непосредственно перед параметром в строке замены идет лексема #, то при подстановке параметр и операция # будут заменены на строку литералов , содержащую имя соответствующего параметра макровызова. В символьной константе или строке литералов, входящих в параметр, перед каждым вхождением \ или " вставляется символ \. Например, если есть макроопределения #define path(logid,cmd) "/usr/" #logid "/bin/" #cmd то макровызов char* mytool=path(joe,readmail); приведет к такому результату: char* mytool="/usr/" "joe" "/bin/" "readmail"; После конкатенации соседних строк ($$R.16.1) получим: char* mytool="/usr/joe/bin/readmail";

R.16.3.2 Операция ##

Если в строке замены между двумя лексемами, одна из которых представляет параметр макроопределения, появляется операция ##, то сама операция ## и окружающие ее обобщенные пробелы удаляются. Таким образом, результат операции ## состоит в конкатенации. Пусть есть макроопределение, #define inherit(basenum) public Pubbase ## basenum, \ private Privbase ## basenum тогда макровызов class D : inherit(1) { }; приведет к такому результату: class D : public Pubbase1, Privbase1 { }; Макроопределение, которое в строке замены соседствует с ##, не подлежит подстановке, однако, результат конкатенации может использоваться для подстановки. Приведем пример. Пусть есть определения: #define concat(a) a ## ball #define base B #define baseball sport Тогда макровызов concat(base) даст в результате sport а вовсе не Bball

R.16.3.3 Повторный просмотр и дальнейшие подстановки

После того, как в строке замены произошла подстановка всех параметров макровызова, получившаяся строка просматривается повторно для обнаружения дополнительных макроопределений. Если в процессе повторных просмотров строки замены найдено имя макроопределения, то подстановка все же не происходит. Рекурсивную подстановку нельзя выполнить как команду препроцессора, хотя она кажется для него естественной командой.

R.16.3.4 Область видимости макроимен и конструкция #undef

После появления макроопределения идентификатор из него считается определенным и остается в текущей области видимости (независимо от правил областей видимости в С++) до конца единицы трансляции или пока его определение не будет отменено с помощью команды #undef. Команда #undef имеет вид: #undef идентификатор Она заставляет препроцессор "забыть" макроопределение с этим идентификатором. Если указанный идентификатор не является определенным в данный момент макроименем, то команда #undef игнорируется.

R.16.4 Включение файлов

Управляющая строка вида: #include <имяфайла> приводит к замене данной строки на содержимое файла с указанным именем. Поиск указанного файла проходит в определенной последовательности частей архива системы и определяется реализацией. Аналогично, управляющая строка вида: #include "имяфайла" приводит к замене данной строки на содержимое файла с указанным именем. Поиск этого файла начинается в особых (системных) частях архива, указанных в начале последовательности поиска. Если там он не найден, то поиск файла идет по всей последовательности, как если бы управляющая строка имела вид: #include <имяфайла> В имени файла, ограниченном символами < и > нельзя использовать символы конца строки или >. Если в таком имени появится один из символов ', \, или ", а также последовательность символов /* или //, то результат считается неопределенным. В имени файла, ограниченном парой символов " нельзя использовать символы конца строки или ", хотя символ > допустим. Если в таком имени появится символ ' или \ или последовательность /* или //, то результат считается неопределенным. Если команда #include строка-лексем имеет вид, соответствующий ни первой, ни второй управляющей строке, то лексемы препроцессора, заданные в этой команде обрабатываются как обычный текст. В результате должна получиться команда, вид которой соответствует одному из приведенных. Она и будет выполнена как положено. Команда #include может быть в файле, который сам появился в результате выполнения другой команды #include. Реализация может накладывать ограничение на глубину вложенности команды #include во входных файлах программы, которые приходится читать для выполнения первоначальной команды #include в одном из входных файлов.