Macros comments

These days I am trying to make a filter serial deviced driver as a study project as a part of this I came across a sample serial monitor filter driver which makes heavy use of C++ classes and MACROS This post is the result of revisit to how macros work.

Token concatenation Token concatenation, also called token pasting, is one of the most subtle — and easy to abuse — features of the C macro preprocessor. Two arguments can be ‘glued’ together using ## preprocessor operator; this allows two tokens to be concatenated in the preprocessed code. This can be used to construct elaborate macros which act much like C ,C++(without many of their benefits). For instance:

#define MYCASE(item,id) \
case id: \ item##_##id = id;\
break
switch(x)
{
MYCASE(widget,23);
}
The line MYCASE(widget,23);
gets expanded here into
case 23: widget_23 = 23;
break;

Now the Macro that has been used in the sample program goes something like this .

#define IMPLEMENT_FUNCTION(x) NTSTATUS \
SERMON##x(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) \
{ \
return ((CDevice *) \
(DeviceObject->DeviceExtension))->x(Irp); \
}
Now when I write something like this : IMPLEMENT_FUNCTION(Read)
It will convert to
SeremonRead(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
return ((CDevice *)
(DeviceObject->DeviceExtension))->Read(Irp);
}

Extern Storage Specifier Also a word about the extern Storage identifier : The extern storage Identifier makes sure that the variable / function is available to files which are outside the source file. i.e. the same variable can be accessed by another source file. E.g. FileA.cpp

extern int i;
incrementFileA() { i++; }
int i=0;
incrementFileA_2() {
i++; }

FileB.cpp
incremenrtFileB() { i++
}
void main()
{
incrementFileA(); incrementFileA_2(); incrementFileB(); }

The values will be 1,2,3. More on MSDN link here Some ofthe other good links for macros and C Preprocessor are http://en.wikipedia.org/wiki/C_preprocessor