11.7  Директивы #pragma

Директивы #pragma позволяют использовать специфичные для конкретных реализаций директивы в форме

#pragma имя-директивы

При помощи директивы #pragma язык C++ позволяет определить любые желаемые директивы, не обращаясь для этого к другим, поддерживающим их компиляторам. Если компилятор не поддерживает данное имя директивы, то он просто игнорирует директиву #pragma, не выдавая при этом никаких сообщений об ошибках или предупреждений.

Язык C++ поддерживает следующие директивы #pragma:

 #pragma alignment

#pragma link

 #pragma argsused

 #pragma message

 #pragma checkoption

#pragma obsolete

 #pragma codeseg

 #pragma option

 #pragma comment

 #pragma pack

 #pragma exit

 #pragma package

 #pragma hdrfile

 #pragma resource

 #ragma hdrstop

 #pragma saveregs

 #pragma inline

 #pragma startup

 #pragma warn

  #pragma once

     

Директива #pragma alignment выдает сообщение о текущем выравнивании данных и размере enum-типов.

Директива #pragma argsused допустима только между определениями функций и действует только на следующую функцию. Она отменяет сообщение уровня предупреждения "Parameter name is never used in function  имя-функции" – ("имя параметра нигде не используется в функции  имя-функции").

Директива #pragma checkoption проверяет, установлены ли опции, указанные в директиве. Если они не установлены, выдается сообщение об ошибке. Синтаксис директивы #pragma checkoption следующий:

#pragma checkoption строка_ опций

Директива #pragma codeseg позволяет указать имя или класс сегмента либо группу, где будут размещаться функции. Если все опции директивы опущены, используется сегмент кода по умолчанию. Синтаксис директивы следующий:

#pragma codeseg [имя_сегмента] ["класс"] [группа]

Директива #pragma comment записывает строку-комментарий в объектный или исполняемый файл. Синтаксис директивы следующий:

#pragma comment (тип, "строка")

Директивы #pragma exit и #pagma startup позволяют программе задать функцию (функции), которая должна вызываться либо при загрузке программы (перед вызовом main), либо при выходе из программы (непосредственно перед выходом из программы через _exit). Синтаксис этих директив следующий:

#pragma exit  имя-функции  <приоритет>

#pragma startup  имя-функции  <приоритет>

Параметр <приоритет> должен являться целым числом в диапазоне от 64 до 255. Старшим приоритетом является 0 (приоритеты от 0 до 63 используются библиотеками языка С/С++ и не должны использоваться пользователем). Функции со старшими приоритетами вызываются первыми при загрузке программы и последними при выходе из нее. Если приоритет не задан, то по умолчанию он равен 100.

Пример

#include <stdio.h>

void startFunc(void)

{

printf("Startup function.n");

}

#pragma startup startFunc 64

/* приоритет 64 —> вызывается при загрузке первой */

void exitFunc(void)

{

printf("Wrapping up execution.n");

}

#pragma exit exitFunc

/* приоритет по умолчанию равен 100 */

void main(void)

{

printf(“This is main.n");

}

Отметим, что функция, имя которой используется в директиве #pragma startup или #pragma exit, должна быть определена (или объявлена) до того, как встретится соответствующая строка с директивой #pragma.

Директива #pragma hdrfile специфицирует имя файла, в котором хранятся прекомпиляционные заголовки. Её синтаксис следующий:

#pragma hdrfile "filename.SYM"

Если программист не использует прекомпиляционные заголовки, то эта директива не будет эффективна.

Директива #pragma hdrstop запрещает включать дальнейшую информацию в файл прекомпилируемых заголовков. Программист может использовать ее, чтобы уменьшить количество дискового пространства, используемого прекомпиляционными заголовками.

Директива #pragma inline сообщает компилятору, что программа содержит встроенные ассемблерные коды. Синтаксис её следующий:

#pragma inline

Эту директиву лучше всего помещать вверху файла, поскольку, встретив директиву #pragma inline, компилятор перезапускает себя с опцией -B. Фактически можно опустить и опцию -В, и директиву #pragma inline, и компилятор, тем не менее, выполнит перезапуск, когда встретит операторы asm. Назначение опции и директивы состоит в том, чтобы сэкономить время компиляции. Таким образом, директива информирует компилятор о том, что файл должен компилироваться через ассемблер (компилятор генерирует код ассемблера, затем запускает TASM, который выдает конечный obj-файл).

Директива #pragma link заставляет компоновщик подключить к исполняемому модулю указанный объектный файл. Синтаксис её следующий:

#pragma link "имяфайла"

Директива #pragma message выдает сообщение при компиляции. Синтаксис её следующий:

#pragma message ("текст"…)

Директива #pragma obsolete выдает предупреждение о том, что данная функция является устаревшей (если имеются обращения к ней). Директивой можно информировать других программистов, что вы усовершенствовали свой код и предусмотрели новую функцию для данной задачи. Синтаксис её следующий:

#pragma obsolete имяфункции

Директива #pragma option используется для включения опций компилятора командной строки в код вашей программы. В одной директиве может находиться любое число опций. Опции компилятора командной строки могут быть любыми, но имеется ограничение. Синтаксис этой директивы следующий:

#pragma option опции #pragma option push опции #pragma option pop

Директива #pragma option позволяет указать необходимые опции командной строки прямо в коде программы. Форма option push сначала сохраняет текущие установки в стеке компилятора; форма option pop выталкивает из стека последний набор опций.

Директива #pragma pack задает выравнивание данных в памяти. Синтаксис её следующий:

#pragma pack(n)

#pragma pack (push, n)

#pragma pack(pop)

Директива #pragma package управляет порядком инициализации модулей в пакетах C++Builder. По умолчанию включается в начало каждого автоматически создаваемого модуля. Синтаксис её следующий:

#pragma package(smart init)

#pragma package(smart init, weak)

Директива #pragma resource помечает текущий файл как модуль формы. В текущем каталоге должны присутствовать соответствующий dfm-файл и заголовок. Всеми этими файлами IDE управляет автоматически. Синтаксис директивы #pragma resource следующий:

#pragma resource "*.dfm"

Директива #pragma saveregs гарантирует, что при входе в функцию huge значения всех регистров останутся без изменений. Данная директива иногда бывает нужна для интерфейса с кодами на языке ассемблера. Директива должна находиться непосредственно перед определением функции. Ее действие распространяется только на данную функцию.

Директива #pragma warn позволяет переопределять конкретные опции командной строки или управлять опцией Display Warnings в диалоговом окне Options | Compiler | Messages). Например, если в вашем исходном коде имеются директивы

#pragma warn +xxx

#pragma warn -yyy

#pragma warn .zzz

то выдача предупреждения xxx будет разрешена (даже если в меню Options | Compiler | Messages она была переведена в состояние off), предупреждения yyy запрещены, а статус выдачи сообщения zzz будет восстановлен в то состояние, которое было к моменту начала компиляции файла.

Существует также специальная директива, указывающая препроцессору, что файл должен быть включен не более одного раза. Эта директива называется ‘#pragma once’. Она использовалась в дополнение к директиве ‘#ifndef’ и в настоящее время устарела и не должна применяться.