I am not a computer science graduate so when I started my career I knew only two languages Hindi and English. I later moved into IT industry as almost every other guy was doing. I went through a crash course on 'C' and before I could learn any other language, my company decided to move me into a client's project. I usually joke when I say I now know three language Hindi, English and 'C' but that is a fact. Since then I have worked on some more computer languages like C++, Perl and Python but I have always felt more comfortable with 'C'.
As I mentioned I learned the basic of 'C' in a 5 days crash course and most of what I now know, I learned from my peers of my various projects. During this time, I first learned what is the right way of writing 'C' macros and later found the explanation of why that is the right way. I decided to share some of those with you in multiple post. So here is the first one.
Let us assume you created a macro as follows:
#define MULTIPLY_BY_TEN( x, y ) x = y * 10
Let us assume the usage of this macro is as mentioned below.
multiply_by_ten_function( one_time )
{
unsigned long ten_times;
MULTIPLY_BY_TEN( ten_times, one_time );
return ten_times;
}
Do you see anything wrong in this? No. I also don't see anything wrong. Actually in this usage, there is nothing wrong. But what do you think about the below usage?
multiply_by_ten_function( one_time, two_time )
{
unsigned long ten_times;
MULTIPLY_BY_TEN( ten_times, one_time + two_time );
return ten_times;
}
Yes. This will have a problem. Why? Because when the macro is expanded it will be :
multiply_by_ten_function( one_time, two_time )
{
unsigned long ten_times;
ten_times = one_time + two_time * 10;
return ten_times;
}
Instead of the addition of 'one_time' and 'two_time' first, it will multiply two_time with 10 and then add one_time to the result. So how do we fix such a thing? Very simple. We always wrap the arguments of a macro with '()'. Now let us look at the macro again:
#define MULTIPLY_BY_TEN( x, y ) (x) = (y) * 10
Now this is how it will look after expanding:
multiply_by_ten_function( one_time, two_time )
{
unsigned long ten_times;
(ten_times) = (one_time + two_time) * 10;
return ten_times;
}
And you will get exactly what you expected. So I hope you will change your habit of not wrapping the arguments of macro with '()'. Please don't believe me and do try this out by writing a small 'C' code to validate the above.
I will put up more such tips in future post. If you want me to write about anything in particular, please leave me a comment.
As I mentioned I learned the basic of 'C' in a 5 days crash course and most of what I now know, I learned from my peers of my various projects. During this time, I first learned what is the right way of writing 'C' macros and later found the explanation of why that is the right way. I decided to share some of those with you in multiple post. So here is the first one.
Let us assume you created a macro as follows:
#define MULTIPLY_BY_TEN( x, y ) x = y * 10
Let us assume the usage of this macro is as mentioned below.
multiply_by_ten_function( one_time )
{
unsigned long ten_times;
MULTIPLY_BY_TEN( ten_times, one_time );
return ten_times;
}
Do you see anything wrong in this? No. I also don't see anything wrong. Actually in this usage, there is nothing wrong. But what do you think about the below usage?
multiply_by_ten_function( one_time, two_time )
{
unsigned long ten_times;
MULTIPLY_BY_TEN( ten_times, one_time + two_time );
return ten_times;
}
Yes. This will have a problem. Why? Because when the macro is expanded it will be :
multiply_by_ten_function( one_time, two_time )
{
unsigned long ten_times;
ten_times = one_time + two_time * 10;
return ten_times;
}
Instead of the addition of 'one_time' and 'two_time' first, it will multiply two_time with 10 and then add one_time to the result. So how do we fix such a thing? Very simple. We always wrap the arguments of a macro with '()'. Now let us look at the macro again:
#define MULTIPLY_BY_TEN( x, y ) (x) = (y) * 10
Now this is how it will look after expanding:
multiply_by_ten_function( one_time, two_time )
{
unsigned long ten_times;
(ten_times) = (one_time + two_time) * 10;
return ten_times;
}
And you will get exactly what you expected. So I hope you will change your habit of not wrapping the arguments of macro with '()'. Please don't believe me and do try this out by writing a small 'C' code to validate the above.
I will put up more such tips in future post. If you want me to write about anything in particular, please leave me a comment.
No comments:
Post a Comment