Friday, October 17, 2008

C++ mutable, finally makes sense

After being a long time basher of C++'s mutable type specifiers, I have finally come to embrace this controversial concept (but its still in beta state :-)

This happened while implementing the FixSession class for my FIXTransit project. I was passing FixSession objects as constant references to other classes, but realized that this wouldn't be possible because some logically-read-only functions might end up modifying the SessionState data member. For example Session::createHeader() whose job is to simply return a FIX message Header for that Session, would result in incrementing the SessionState::seqNum property.

So now that the rationale behind the divine concept had occured to me, I very proudly declared the SessionState data member as mutable and continued to pass the Session objects as logically constant references :-)

Now I might end up in revisiting and changing this design altogether, however I feel that I have learned an important lesson from this. Also I would still maintain that this is not an ideal approach and should be adopted in very rare situations.

Friday, May 30, 2008

Touch Windows

As you might have heard by now, Microsoft is introducing touch screen technology in Windows 7; Microsoft's next operating system release

http://news.bbc.co.uk/2/hi/technology/7422924.stm

Well this is an interesting concept and Bill Gates being a great envisioner, is I think right in predicting that in future the ways we interact with our PCs would change.I also expect(and hope) this release of windows to get a better reception than Vista, which was a TOTAL flop.

Also don't get fooled by Ballmer's comment of selling 150 million copies of Windows Vista. This number does'nt show that it was successfull or people liked it. Those number just show that how powerfull Microsoft is and on the contrary how helpless the rest of the world is. Vista sucked; everyone knew it but still they had no other option but to buy and use it. The reason being that all new laptops were getting shipped with Vista. You actually had to customize your laptop, pay extra and even wait more to get Windows XP installed. Unfortunately even if Windows 7 is crapy, people would still buy, use and eventually like it. The reason being that In the PC market there is simply no alternative to Windows (Apple is too expensive and Linux is too geeky)

Fortunately, being a Gnu Linux and open source software user I don't fall under this helpless category. Whenever I buy a laptop the first thing I do is that I repartition, remove Windows install Linux and other free software.

Tuesday, May 20, 2008

A simple but EFFECTIVE debugging technique

Debugging with printf:
================

Even with all the sophisticated debugging tools out there, as developers I guess all of us will agree that printf still remains one of the most convenient and heavily used debugging aids. Whether you are writting new code or trying to debug existing one, there is nothing like good old printf :)

printf not acceptable in production:
=========================

Having said that, we all would agree that nobody would want printfs or fprintf's in their production code. A few reasons for that being:

1. printf messages clutters the stdout and considering that these messages are coming straight from developers hearts, you would DEFINITELY not want to expose them to your clients

2. You must be thinking, "well I can use fprintf instead and redirect the debug messages to a file and add a secret command line parameter to run the program in debug mode". There are still two issues with this;
(i) Your source code will be cluttered with alot of if statements. Even worst the program will have to perform the if (mode == DEBUG) type of tests where ever you have printed debug message(s). If your application is large and runs in real time these tests could prove to be a considerable performance bottleneck.
(ii) (i) is bad but it isn't the worst part. The worst is that the if statements and their corresponding bodies will contribute to the binary size, thus killing the performance of your program (see 3 for details)

3. Debug messages will increase the size of the code section part of the binary, which means that they would considerably effect performance.

Preprocessor directives to the rescue:
===========================

Thus the question is "how do I add debug statements to my program, but at the same time not add debug statements to my program :)". Well the answer to this dilemma is, the use of preprocessor directives (#if). Add the debugging code under a preprocessor directive and compile it conditionally.

#if DEBUG
/* print crazy debug messages or perform some other debugging operations */

#endif

Now whenever I need debug messages I can turn them on by compiling my program with the DEBUG macro defined.

The following small program demonstrates the use of this technique:

3
4 #define DEBUG 1
5
6 int main(int argc, char *argv[])
7 {
8 printf("Hello World\n");
9 #if DEBUG
10 printf("Debugging is enabled\n");
11 #endif
12 return 0;
13 }


Note how we are defining DEBUG at line 4. Also note how we are using it in a preprocessor directive at line 9

9 #if DEBUG
10 printf("Debugging is enabled\n");
11 #endif


Compiling and running the program would yield the following output

Hello World
Debugging is enabled


Now undefine DEBUG by updating line 4 as follows

4 #define DEBUG 0


Compile and execute the program. You should get the following output

Hello World


Not only did the execution of what ever was between #if DEBUG ... #endif was avoided, but it was not even included in the compiled binary. Hence we achieved our goal, i.e. "we added debug statements to our program, but at the same time did not add debug statements" :)

There is a much elegant want to define the DEBUG marco; Remove line 4 of the above program and compile it with gcc's -D option:

gcc -o test -DDEBUG=1 test.c


You can now include the debug messages in your production level code and commit it to your SCM's release branch(however DO make sure to write it under preprocess directives).

Please note that I am in no way denying the importance of debuggers, they are a VERY important component of developing stable software, however there are scenarios where outputing messages are more convenient and that is where this approach comes handy.

Sunday, May 18, 2008

Simple Makefile Tutorial

The purpose of this tutorial is to create and understand a simple Makefile without the use of autotools (autoconf, automake etc).

Make Utility
=========

From the make manpage "The purpose of the make utility is to determine automatically which pieces of a large program need to be recompiled, and issue the commands to recompile them"

Normally, you would use the make utility when your program's source code includes more than one file. By virtue of this utility, if you make changes to a particular module, you will not be required to recompile the whole program. It will recompile only the changed modules and the modules that dependent on them.

The Makefile
==========

The make utility takes a Makefile or description file as input. In this file you specify the modules to build and their corresponding dependencies.

When invoked, the make utility expects a file named Makefile to be present in the same directory and uses it as its description file.

Makefile Format
============

The dependencies in the Makefile are specified using the following syntax:

target: components
TAB rule


In the first line you specify the target name and its dependencies whereas the second line comprises of the rule(s) to build the target. Note that in the rules line the TAB is mandatory, otherwise make will not be able to parse correctly and an error will be generated.

Invoking make
==========

make is invoked simply by entering make on the command line. It should be invoked from the same directory where you have defined your Makefile.

make

By default make will start building the first target defined in your Makefile. However you can also instruct make to build a specific target via the following syntax:

make target-name


Example
======

Lets jump straight to an example and implement what we have learned. Below is a simple Makefile. It builds a program named test:

test: test.o
gcc -o test test.o

test.o: test.c
gcc -c test.c


The target test depends on test.o and it is built by issuing the command gcc -o test test.o. If test.o is modified then make will build test again. Similarly test.o is itself another target which depends on test.c. If test.c is modified then test.o is rebuilt using its corresponding rule.

In the above scenario we were only dealing with one source file. We would have been good by simply using gcc as well. Lets take a slightly more complicated example:

Suppose you are implementing a stack and you want to write a program; stacktest that tests this implementation. The stack is being implemented by wrapping around another container called vector.

Hence, stacktest depends on stack and stack depends on vector. The corresponding Makefile can be written as follows:


stacktest: stacktest.o stack.o vector.o
gcc -o stacktest stacktest.o stack.o vector.o

stacktest.o: stacktest.c stack.h
gcc -c stacktest.c

stack.o: stack.c stack.h vector.h
gcc -c stack.c

vector.o: vector.c vector.h
gcc -c vector.c

Adding the clean target
=================

Traditionally each Makefile comes with a clean target. The purpose of this target is to remove all the object files and targets so that the next time you invoke make everything is re-compiled. Lets add a clean target in our stacktest example:

clean:
rm -f *.o
rm -f stacktest

As you can see, in our clean target we are removing all the object files and the stacktest binary. This target can be invoked as follows:

make clean


Hope you found this helpfull!

Wednesday, May 14, 2008

Function overloading In C

Background:
=========

A few days back, me and my friend were discussing if it would be possible to implement function overloading in C. We discussed a few approaches but none seemed to provide a complete solution. So as you would expect from a developer, as soon as I came back home, I started working on it. Consequently after 2 days worth of work I came up with coverload.h . Just include this file in your code and start overloading in C :)
#include "coverload.h"

By using the macros defined in this file you can imitate function overloading. I would not say that its a 100% solution, but very close.

Basic Idea:
========

As in C++, we rely on name decoration (or name mangling) to mangle the names of functions. For example:

void foo(int x,float y) will be name mangled to something like void fooint_float(int x,float y)

Function Declaration:
===============

All functions should be declared using the DECL_FUNC macro:

DECL_FUNC(function_name, return_type, parameters)

Where:

function_name: name of the function
return_type: is the return type of the function (DAH!!!)
parameters: A comma seperated list of parameters. Each parameter is specified via the PARAM(type,name) macro

For Example:
Here is how you can declare a function named foo, having return type int and taking double and long parameters:

DECL_FUNC(foo,int,PARAM(double,dparam),PARAM(long,lparam))
{
.....
}

And this is how you will overload the above function:

DECL_FUNC(foo,int,PARAM(int,iparam))
{
......
}


Function Invocation:
===============


To invoke a function, the INVOKE_FUNC macro should be used:

INVOKE_FUNC(FUNCNAME_FROM_TYPES(func_name,arg_types),arg1,arg2,arg3,...)

Where:

func_name: name of the function
arg_types: a command seperated list of arg types
arg1,arg2... : a comma seperated list of arg values



Note that we need to invoke the FUNCNAME_FROM_TYPES arguments to construct the name of the
actual function to invoke.

For Example:
In order to invoke a function named foo having a double and long parameter do the following:

INVOKE_FUNC(FUNCNAME_FROM_TYPES(foo,double,long),4.5,20L)


Below we invoke the overloaded version of foo, that takes one int parameter:

INVOKE_FUNC(FUNCNAME_FROM_TYPES(foo,int),4)


Limitations:
========
  • I have'nt done any real testing for now (will do it at my earliest and publish the bug fixes)
  • Right now this can only work with 5 function parameters. However as you can see from the macro definitions, adding support for more parameters is very easy (mere copy paste) now. Also I am currently working on a script that will auto-generate the coverload.h file. It will be published as soon as it gets completed.
  • I have'nt tested the code with pointers. So for now you cannot use pointers with "*". However if you really want to use pointers, there is a workaround; If you typedef your pointers , you should be fine.
Examples:

You can find some usage examples in overload.c