Использование препроцессора

Здесь перечислены директивы препроцессора, которые поддерживают Tibbo BASIC и Tibbo C.

#define

Создаёт макрос - связь идентификатора препроцессора со строкой токенов.

#define RED 0
#define GREEN 1
#define BLUE 2
#define COLOR BLUE 

В TIDE есть и «глобальные» идентификаторы препроцессора. Их можно просмотреть в диалоге Customize Project (File > Project Settings - > Customize (button)).

В диалоге показаны глобальные идентификаторы, которые поступают непосредственно из файлов платформы. Значения некоторых идентификаторов можно изменять. Можно также определять собственные глобальные идентификаторы.

Как и идентификаторы, определённые директивой #define, все эти глобальные идентификаторы можно использовать в описанных ниже условных конструкциях препроцессора.

Отличие идентификаторов препроцессора, определённых директивой #define, от глобальных в том, что глобальные идентификаторы можно дополнительно использовать для задания условий компиляции файлов.

#undef

Отменяет (удаляет) текущее определение идентификатора препроцессора.

#define GREEN 1
...
#undef GREEN

#ifdef-#else-#endif

Конструкция условной компиляции, проверяющая, существует ли указанный идентификатор препроцессора.

#define GREEN 1
...
dim s as string
#ifdef GREEN
   'code here will be included
   s="GREEN is defined"
#else
   'code here will not be included
   s="GREEN is not defined"
#endif
#define GREEN 1
...
string s;
#ifdef GREEN
   //code here will be included
   s="GREEN is defined";
#else
   //code here will not be included
   s="GREEN is not defined";
#endif

#if defined (только C)

Более продвинутая версия #ifdef, позволяющая задавать составные условия.

Обратите внимание: в конструкции #if defined идентификаторы макросов необходимо заключать в скобки.

#define PRINTER 1
#if defined(PRINTER) && !defined(ABC)
   'code here will be included
#endif

#ifndef-#else-#endif

Конструкция условной компиляции, проверяющая, что указанного идентификатора препроцессора не существует.

#define GREEN 1
...
dim s as string
#ifndef GREEN
   'code here will not be included
   s="GREEN is not defined"
#else
   'code here will be included
   s="GREEN is defined"
#endif
#define GREEN 1
...
string s;
#ifndef GREEN
   //code here will not be included
   s="GREEN is not defined";
#else
   //code here will be included
   s="GREEN is defined";
#endif

#if-#elif-#else-#endif

Конструкция условной компиляции, вычисляющая выражение с идентификаторами препроцессора.

Напоминание: некоторые операторы сравнения и логические операторы в BASIC и C различаются. То, что в BASIC записывается как #if COLOR=RED, в C будет #if COLOR==RED!

#define RED 0
#define GREEN 1
#define BLUE 2
#define COLOR GREEN
#if COLOR=RED
   'code here will not be included
#elif COLOR=GREEN
   'code here will be included
#else
   'code here will not be included
#endif
#define RED 0
#define GREEN 1
#define BLUE 2
#define COLOR GREEN
#if COLOR==RED
   //code here will not be included
#elif COLOR==GREEN
   //code here will be included
#else
   //code here will not be included
#endif

#include (C); include (BASIC)

В BASIC файлы подключаются оператором include, который формально не является частью препроцессора.

Здесь он рассматривается вместе с директивой препроцессора C #include, потому что выполняют они совершенно одну и ту же работу.

'remember, headers files must be included,
'it's not enough to just have them in the project tree
include "global.tbh"
//remember, headers files must be included,
//it's not enough to just have them in the project tree
#include "global.tbh"

#includeb (только C)

Позволяет подключить заголовочный файл BASIC (.TBH) из файла C. Это мощный инструмент: с ним не нужно держать два одинаковых заголовочных файла с определениями - один для BASIC и зеркальный для C.

Обратной директивы, подключающей заголовки C из файлов BASIC, не существует.

dim ctr as byte
include "global.tbh"
sub on_sys_init
   ctr=0
end sub
#includeb "global.tbh"
void on_sys_timer(){
   ctr++; //a separate declaration of ctr in the C style is not required
}

#includepp

Особенность препроцессора Tibbo - директивы препроцессора можно включать в текстовые файлы ресурсов.

Это широко применяется в библиотеках. Например, библиотека STG опирается на settings.xtxt - файл определений со списком настроек, их именами, типами и так далее.

Обычно с этим файлом работают через удобный конфигуратор. Если заглянуть в содержимое самого текстового файла, там можно увидеть несколько директив #define.

Чтобы TIDE распознал эти директивы, нужно включить этот текстовый файл ресурсов в процесс компиляции директивой includepp.

includepp "settings.xtxt"
'define an arrays with the number of elements equal to the #define made in a
'text resource file
dim arr(STG_MAX_NUM_SETTINGS) as byte
 
#includepp "settings.xtxt"
//define an arrays with the number of elements equal to the #define made in a
//text resource file
unsigned char arr[STG_MAX_NUM_SETTINGS];
...
#define STG_MAX_NUM_SETTINGS 40

#message

Выводит сообщение на панель Output (не забудьте заключить строку сообщения в "").

...
#if COLOR=RED
   #message "The color is RED"
#elif COLOR=GREEN
   #message "The color is GREEN"
#else
   #message "The color is BLUE"
#endif
...
#if COLOR==RED
   #message "The color is RED"
#elif COLOR==GREEN
   #message "The color is GREEN"
#else
   #message "The color is BLUE"
#endif

Пример вывода компилятора (сокращённо) для приведённого выше кода:

Building...
Compiling main.tbs...
(prj)\main.tbs(4): message: The color is BLUE
Linking...
Build complete.

#error

Выводит сообщение на панель Output и прерывает компиляцию (не забудьте заключить строку сообщения в "").

...
#if COLOR=RED
   #message "The color is RED"
#elif COLOR=GREEN
   #message "The color is GREEN"
#elif COLOR=BLUE
   #message "The color is BLUE"
#else
   #error "Unsupported color. Compilation aborted."
#endif
...
#if COLOR==RED
   #message "The color is RED"
#elif COLOR==GREEN
   #message "The color is GREEN"
#elif COLOR==BLUE
   #message "The color is BLUE"
#else
   #error "Unsupported color. Compilation aborted."
#endif

Пример вывода компилятора (сокращённо) для приведённого выше кода:

Building...
Compiling c.tc...
(prj)\c.tc(142): #error: Unsupported color. Compilation aborted.

#pragma pack (только C)

Возможные значения: #pragma pack (1), (2) или (4).

Указание #pragma pack (2) приводит к 16-битному выравниванию в структурах и объединениях (для правильного выравнивания добавляются нулевые байты заполнения).

Использование #pragma pack (4) приведёт к 32-битному выравниванию.

В Tibbo BASIC такой конструкции нет, поскольку там применяются «безопасные» структуры со специальными заголовками. Для таких «безопасных» структур «упаковка» не имела бы смысла.

В Tibbo C по умолчанию действует (1), то есть никакого заполнения нет.

struct test_unpacked{
   unsigned char x; //occupies one byte
   unsigned long l; //occupies four bytes
};
#pragma pack (4) //this will affect all definitions below
struct test_packed{ //this structure will be with padding
   unsigned char x; //occupies one byte
   unsigned long l; //occupies four bytes
};
test_unpacked tu;
test_packed tp;
void on_sys_timer(){
   sys.debugprint(str(sizeof(tu))+", "); //Will print "5" (unsigned char + unsigned long need 5 bytes)
   sys.debugprint(str(sizeof(tp)));      //Will print "8" because 3 padding bytes will be added after the unsigned char
}

При #pragma pack (4) и значениях tp.x=0x12 и tp.l=0x3456789A структура памяти, содержащая переменную tp, будет выглядеть так (обратите внимание на три нулевых байта заполнения):

0x120x000x000x000x9A0x780x560x34

#pragma message (только C)

Существует для совместимости с другими реализациями C; того же результата можно добиться директивой #message.

Исходный материал Tibbo обновлён 22 августа 2022Оригинал на docs.tibbo.com · Сообщить об ошибке