Using Preprocessor

Top  Previous  Next

Here are 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 (settings) library relies on the 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

 

Example compiler output (abridged):

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

 

Example compiler output (abridged):

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 the 16-bit alignment in structures and unions (zero-byte padding is used to achieve proper alignment).

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

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

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.