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.
Friday, May 30, 2008
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 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
(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 (
Now whenever I need debug messages I can turn them on by compiling my program with the
The following small program demonstrates the use of this technique:
Note how we are defining
Compiling and running the program would yield the following output
Now undefine
Compile and execute the program. You should get the following output
Not only did the execution of what ever was between"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
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.
================
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. 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
When invoked, the
Makefile Format
============
The dependencies in the Makefile are specified using the following syntax:
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
Invoking make
==========
By default
Example
======
Lets jump straight to an example and implement what we have learned. Below is a simple Makefile. It builds a program named test:
The target
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
Hence,
Adding the clean target
=================
Traditionally each Makefile comes with a
Hope you found this helpfull!
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 :)
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:
Function Declaration:
===============
All functions should be declared using the
Where:
For Example:
Here is how you can declare a function named foo, having return type int and taking double and long parameters:
And this is how you will overload the above function:
Function Invocation:
===============
To invoke a function, the
Where:
Note that we need to invoke the
actual function to invoke.
For Example:
In order to invoke a function named foo having a double and long parameter do the following:
Below we invoke the overloaded version of foo, that takes one int parameter:
Limitations:
========
You can find some usage examples in overload.c
=========
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 theactual 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.
You can find some usage examples in overload.c
Subscribe to:
Posts (Atom)