Showing posts with label programming. Show all posts
Showing posts with label programming. Show all posts

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.

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.

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