PHP Extensions: understanding preprocessors

10 May

In my first example, where I discuss building a simple extension, you can see lots of #defined statements. These are preprocessor macros. So before going into details of building extension, it will be worth understanding these.

C’s preprocessor is text editor phase in compilation process. It loads up the commands and uses them to modify the source code. As all this is happened before the compiler is involved, you can use anything even C keywords as macro for macros definition. The only keyword that cannot be used as macro is defined.

Macros can be define either object like or function like.

Object like macros can be defined as

#defined NULL 0

#defined NULL (void*) 0

The type is mostly used for constants that may change later in the code. E.g

#defined HEIGHT 67

#defined WIDTH 70

These can also be used to defined expressions like

#defined HALFHEIGHT HEIGHT/2

Here you can see that we have defined macro by using already defined macro.

Function like macros have parenthesis, an example can be

#defined max(a,b) (a>b?a:b)

Later in the code if you write max(6,4). This will be substituted to (6>4?6:4).

You can even write max(,7)

However if you write max(k+1,4), in this case this will not be substituted to what you expect. To achieve this you will need to put some extra parenthesis like the following.

#defined max(a,b) ((a)>(b) ?(a):(b))

Keep in mind that using sting as macros is a bit tricky. Take a look at the following example.

#defined plot(m) me “me”

And later you write

plot(zend)

This will be substituted to

zend “me”

you can examine that first one is substituted while the string in the quotes doesn’t.

To properly defined string in quotes, write

#defined p(string) printf(“%s”,#string)

Now when you use

p(“hello”)

This will be substituted to

printf(“%s”,”hello”);

Because of using # before string, the string  will be placed in the code when substituted.

Keep in mind that anything enclose in the double quotes is not substituted.

Another important thing is that if you defined

#defined mo(cat) “Error:”#cat

And later write

printf(“%s”, mo(no such cat));

This will be substituted to

printf(“%s”,”Error:no such cat”);

If you want to concatenate strings, removing spaces and pound signs, write

#defined concat(a,b) a##b

concat(2,1) will yield 21.

Well, in my first extension building example if does defined macros, however most of them were defined on conditions.

So let have a look at how to defined macros based on condition.

The general syntax is

#if expression

#endif

If the expression isn’t true means zero “0” then the code after the if condition is not include, otherwise its included.

A basic example can be

#if MAX > 80

#defined MIN 100

#endif

Another example can be

#defined MAX

#if defined MAX

And similarly

#if !defined MAX

Anther form can also be used

#ifdef MAX

And

#ifndef MAX

Another very good example would be usage of if-elif like this

#if expression1

….

#elif expression2

….

#elif expression3

#else

….

#endif

This example states that if the first expression is true, include what follow the expression1, if not check the second expression. Check all the expression. If non of them is true, include the what follows the else part.

What if you have defined a macro and you want to remove that?

Well, this can be achieved by using

#undef

macro.

Like

#defined MAX 200

#undef MAX

Well, when it comes to c preprocessor there are predefined macros like

__FILE__

__LINE__

__DATE__

__TIME__

__STDC__

__STD_HOSTED__

__STD_VERSION__

__func__

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: