OpenSCADAWiki: Roman Savochenko/C Short All/part1/part8
 

1.8 Препроцессор

Препроцессор это часть языка С. Препроцессор считывает исходный код, отвечает на размещенные в нем директивы и производит модифицированную версию этого исходного кода, которая передаётся компилятору. Подстановки препроцессором выполняются рекурсивно, т.е выполняется многопроходная обработка.

#define VAL_T 345
 #undef VAL_T
 #define VAL_T 234

#define FILLSCREAN(color) _AX = 0x0600;\
                           _CX = 0x0000;\
                           _DX = 0x184f;\
                           _BH = color;\
                           geninterrupt(0x10);

#define min(a,b) ((a) < (b) ? (a) : (b))
 result = min(44,uplimit);   
 // result = ((44) < (uplimit) ? (44) : (uplimit));

#define var( i , j ) ( i##j )   // var( x , 6 ) = x6

#define TRACE(flag) printf(#flag "=%d\n", flag)

#define err(...) fprintf(stderr,__VA_ARGS__)
 err("%s %d\n","The error code ",48); 
 // fprintf(stderr,"%s %d\n","The error code ",48);

 #define errout(a,b,...) \
     fprintf(stderr,"File %s  Line %d\n",a,b); \
     fprintf(stderr,__VA_ARGS__)
 errout(__FILE__,__LINE__,"Unexpected termination\n");

1.8.1 Директивы Препроцессора

_Pragma
_Pragma("GCC poison printf")
Оператор для вызова прагмы из тела макроса (табл.7).

#define
#define ident ident1;
Заменяет все последующие определения <ident> на лексему <ident1> (совокупность лексем).

#elif, #if
#if expresion
#elif expresion1
#endif
Проверяет выражение <expresion>, связанное с директивами #if, или #elif , если выражение истинно (отличный от нуля), то выполняются следующие строки до директив условия или конца условий. Директива #elif является объединением директив #else и #if. Если имеется #else, то нижестоящие строки выполняются когда выражение в #if или #elif имеет нулевое значение. Нельзя использовать в качестве условия оператор sizeof, составные типы, float или enum типы.

defined
#if defined(VAR)
#elif !defined(NVAR)
#endif
Оператор проверки определённости, используется в паре с #if.

#else
Нижестоящие строки выполняются если выражение в #if, #ifdef, #ifndef или #elif имеет нулевое значение.

#endif
Указывает на конец условия.

#error
#error сообщение
Генерация сообщения ошибки на stderr и завершения процесса компиляции.

#ifdef
#ifdef <identifier>
Выполняет последующие строки до #endif, если <identifier> был ранее определен.

#ifndef
#ifndef <identifier>
Выполняет последующие строки до #endif, если <identifier> не был ранее определён.

#include
#include <filename>
Вставляет содержимое файла <filename> в текущий файл. Если путь к имени файла включен в двойные кавычки ,то поиск осуществляется внутри текущего каталога.

#include_next
#include_next <filename>
?

#line
#line n file
Изменяет внутренний номер строки компилятора на <n>, а также изменяет внутреннее имя файла на <file>. Текущий номер строки и имя файла доступны через константы препроцессора __LINE__ и __FILE__.

#pragma
#pragma directives
Инструктирует компилятор, о выполнение машинно-специфических возможностей, определенных параметром <directives> (таблица [*]).

#undef
#undef identifier
Удаляет текущее определение <identifier>, который был предварительно определен директивой #define.

#warning
#warning сообщение
Генерация сообщения предупреждения на stderr и продолжение компиляции.

Таблица 7. Параметры директивы pragma, препроцессора
Имя
Назначение
packОпределяет, как компилятор выравнивает данные при сохранении в памяти. Может также использоваться с, вталкиванием и выталкиванием параметров.
#pragma pack(n) 
#pragma pack(push, n) 
#pragma pack(pop)

Таблица 8. Предопределённые символьные константы
Имя
Назначение
__BASE_FILE__Полный путь к каталогу исходного файла.
__CHAR_UNSIGNED__Указывает на то, что символьный тип является безнаковым.
__cplusplusУказывает на то, что исходный код является программой на языке С++.
__DATE__Дата компиляции исходного файла (строка).
__FILE__Имя исходного файла (строка).
__func__Имя текущей функции.
__FUNCTION__Имя текущей функции.
__PRETTY_FUNCTION__Полное имя текущей функции. Для C++ включает имена классов.
__INCLUDE_LEVEL__ Глубина включения (include) файла.
__LINE_Номер текущей строки исходного текста (целое число).
__NO_INLINE__Указывает на отсутствие inline-функций.
__OBJC__Программа на языке Objective-C.
__OPTIMIZE__Указывает на то, что назначен уровень оптимизации.
__OPTIMIZE_SIZE__Оптимизация размера программы.
__STDC__Компилятор соответствует правилам стандарта языка C.
__TIME__Время компиляции исходного файла (строка).
__VERSION__Полный номер версии.