Using the Preprocessor

Here are the preprocessor directives supported by Tibbo BASIC and Tibbo C.


#define

Creates a macro, which is the association of the preprocessor identifier with a token string.

Tibbo BASIC or C
#define RED 0 
#define GREEN 1
#define BLUE 2
#define COLOR BLUE 

TIDE also features "global" preprocessor identifiers. You can inspect them in the Customize Project dialog (File > Project Settings —> Customize (button)).

The dialog shows global identifiers that come directly from platform files. Some identifiers allow you to alter their values. You can also define your own global identifiers.

Like identifiers defined with the #define directive, all these global identifiers can be used in conditional preprocessor constructs described below.

The difference between preprocessor identifiers defined using the #define directive and the global ones is that global identifiers can additionally be used in setting file compilation conditions.


#undef

Un-defines (removes) the current definition of the preprocessor identifier.

Tibbo BASIC or C
#define GREEN 1
...
#undef GREEN

#ifdef—#else—#endif

Conditional compilation construct that checks if the specified preprocessor identifier exists.

Tibbo BASIC
Tibbo C
#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 Only)

This is a more sophisticated version of #ifdef, it allows you to set compound conditions.

Note how the #if defined construct requires parentheses around macro identifiers.

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

#ifndef—#else—#endif

Conditional compilation construct that checks if the specified preprocessor identifier does not exists.

Tibbo BASIC
Tibbo C
#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

Conditional compilation construct that evaluates an expression involving preprocessor identifiers.

Reminder: Some relational and logic operators differ between BASIC and C. What's #if COLOR=RED in BASIC is #if COLOR==RED in C!

Tibbo BASIC
Tibbo C
#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)

In BASIC, files are included with the include statement, which is technically not a part of the preprocessor.

I am combining this with the C preprocessor directive #include, because the two do exactly the same job.

Tibbo BASIC
Tibbo C
'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 Only)

Allows you to include a BASIC header file (.TBH) from a C file. This is a powerful tool that you can use to avoid having two identical header files with definitions — one for BASIC and a mirror one for C.

The reverse directive for including C headers from BASIC files does not exist.

Tibbo BASIC header file
dim ctr as byte

Tibbo BASIC
Tibbo C
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

One special feature of our preprocessor is that preprocessor directives may be included in text resource files.

This is widely used in libraries. For example, the STG library relies on settings.xtxt, which is a definition file carrying the list of settings with their names, types, etc.

You typically work with this file through a convenient configurator. If you were to look at the contents of the underlying text file you would see that there are several #define directives in that file.

To make TIDE recognize these directives you need to include that text resource file into your compilation process using the includepp directive.

Tibbo BASIC
Tibbo C
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];

settings.xtxt (text resource file)
...
#define STG_MAX_NUM_SETTINGS 40

#message

Prints a message into the Output pane (don't forget to put "" around the message string).

Tibbo BASIC
Tibbo C
...
#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

The example compiler output (abridged) for the above would be:

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

#error

Prints a message into the Output pane and aborts the compilation (don't forget to put "" around the message string).

Tibbo BASIC
Tibbo C
...
#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

The example compiler output (abridged) for the above would be:

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

#pragma pack (C Only)

Possible values are #pragma pack (1), (2), or (4).

Specifying #pragma pack (2) leads to 16-bit alignment in structures and unions (zero-byte padding is used to achieve proper alignment).

Using #pragma pack (4) will lead to 32-bit alignment.

The same construct doesn't exist in Tibbo BASIC, because it uses "safe" structures featuring special headers. "Packing" wouldn't make any sense for such "safe" structures.

The Tibbo C default is (1); i.e., no padding of any kind.

Tibbo C
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
}

With #pragma pack (4), and assuming that tp.x=0x12 and tp.l=0x3456789A, the memory structure holding the tp variable will look like this (notice three padding zero bytes):

0x12

0x00

0x00

0x00

0x9A

0x78

0x56

0x34


#pragma message (C Only)

Exists for compatibility with other C implementations; the same is achieved with the #message directive.


Using the Preprocessor

#define

#undef

#ifdef—#else—#endif

#if defined (C Only)

#ifndef—#else—#endif

#if—#elif—#else—#endif

#include (C); include (BASIC)

#includeb (C Only)

#includepp

#message

#error

#pragma pack (C Only)

#pragma message (C Only)