Кроме рассмотренных ранее директив #include, #define и директив команд условной компиляции существует еще несколько вспомогательных директив, которые не так часто используются в практике программирования.
Директива #line позволяет управлять нумерацией строк в файле с программой, а также изменять имя файла.
После препроцессорной обработки каждая строка текста передаваемого на компиляцию имеет следующий вид:
имя_файла номер_строки: текст_на_языке_С++
Директива #line имеет следующий формат:
Для нумерации строк можно использовать директиву
#line номер_строки [“имя_файла”]
Данная директива позволяет изменять номер и имя файла следующей за ней строки на указанные значения.
Пример:
Препроцессор получает для обработки файл "www.c" с текстом:
#define N 3 // строка 1
void main ( ) // строка 2
{ // строка 3
#line 23 "file.с" // строка 4
double z[3*N]; // строка 5
} // строка 6
После препроцессорной обработки в файле с именем "www.i" будет получен следующий набор строк:
www.c 1:
www.c 2: void main ( )
www.c 3: {
www.c 4:
file.c 23: double z[3*3]
file.c 24: }
Из текста исключены препроцессорные директивы и комментарии. При этом строки, где размещались директивы препроцессора (1 и 4), вошли в компилируемый текст, как пустые строки. Следующей за директивой #line строке присвоен номер 23 и имя файла "file.c" в соответствие с указанными значениями. Следующая строка имеет такое же имя файла и номер строки на единицу больше.
Директива #line может использоваться в случае, когда текст программы на языке С++ генерирует какой-то другой препроцессор.
Директива #errorзадает текст сообщения, которое выводится при возникновении ошибок компиляции.
Она имеет следующий формат:
#error текст_сообщения
Выполнение данной директивы приводит к выдаче диагностического сообщения, содержащего указанный текст. Текст может содержать препроцессорные идентификаторы. Директива #error может применяться совместно с директивами условной компиляции.
Пример:
Определив некоторую препроцессорную переменную NAME
#define NAME 5
можно проверять, не изменилось ли ее значение, и выдавать в этом случае сообщение:
#if (NAME != 5)
#error NAME должно быть равно 5
В интегрированной среде (например, Turbo С) сообщение будет выдано на этапе компиляции в виде:
Fatal <имя_файла> <номер_строки>:
Error directive: NAME должно быть равно 5
В случае выявления такой аварийной ситуации дальнейшая препроцессорная обработка исходного текста прекратиться, и в компилируемый текст попадет только та часть текста, которая предшествует директиве #if.
Директива #pragma вызывает действия, зависящие от конкретной реализации компилятора.
Она имеет следующий формат
#pragma последовательность _лексем
Данная конструкция называется прагмой. Стандарта для прагм не существует. Если конкретный препроцессор встречает прагму, которая ему неизвестна, он ее игнорирует.
В некоторых реализациях включена директива
#pragma pack(n)
n может быть равно 1, 2 или 4.
Данная прагма позволяет влиять на упаковку смежных элементов в структурах и объединениях. Соглашение может быть таким:
pack(l) - выравнивание элементов по границам байтов;
раск(2) - выравнивание элементов по границам слов;
раск(4) - выравнивание элементов по границам двойных слов.
В некоторые компиляторы включены прагмы, позволяющие изменять способ передачи параметров функциям, порядок помещения параметров в стек, сообщать компилятору о наличии в тексте программы команд на языке ассемблера и т.д.
Существует также пустая директива, использование которой не вызывает никаких действий. Она имеет вид: