Showing posts with label Software development. Show all posts
Showing posts with label Software development. Show all posts

Sunday, November 10, 2013

One tip on C macros

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.

 

Saturday, August 31, 2013

Defects : Can they be avoided?

If you happen to be working in the IT industry, I can bet that you would have come across the word 'Defect' (or other popularly used word 'Bug') almost on daily basis. A 'defect' is nothing but a case of something not working as expected.

You can see defects usually in all walks of life. There are defects in the house you live, bus you take, car you drive, laptop you use. You would have seen various manufacturers recalling their products because they want to fix a defect.

Why one should worry about defects? Because defects are usually costly. Each defect has a cost associated to it. Cost of each defect depends upon which phase it got introduced and which phase it got caught. A defect that was introduced in design phase and caught in deployment phase will be the most costly defect. In the worst case, a defect could be life threatening. For example, a small defect brought down the space shuttle Columbia where all the astronauts were killed.

The big question is why and how defects get introduced?

In any product development, there are various stages. Let us take an example of software product as I am more familiar with this. We can divide the software product development in various stages like requirement collection, high level design, low level design, user-interface design, implementation, testing, deployment etc.. Defects get introduced in almost every stage.

Someone may ask, how come defects gets introduced in the testing phase. Actually testing is suppose to figure out all defects but as we know by experience that it is not the case. So this means that there is some defect in our testing because of which we are not able to detect all defects.

When you designs your product, it is almost impossible to test the design for all possible inputs. So there will always be some inputs for which you cannot test your design or implementation. So theoretically, there is a possibility that your design may fail for some such input. If I extend the above, we can safely say that in theory, it is almost impossible to avoid defects. Similarly, a developer without required level of skills, implementing the desgin will introduce more defects.

In my opinion, as mentioned above, in a completely new software, defects are introduced in all the stages. Once defects are seen, they are fixed. This is when more defects are introduced in the software. So this becomes a unavoidable cycle.

Why defects are introduced when fixing a defect? There could be various reasons like the developer does not know the big picture or there is not enough documentation about the implementation or there is no review process or the developer's skills are not good enough. In my opinion, review process can help in most of these cases. For example: even if the developer fixing the defect does not know the big picture, the chances of getting defects can be reduced if an expert review the fix. In one of my earlier post, I had talked about the necessity of code review. In that post, I argued in favour of code review which helps in reducing the defects in the system.

So defects are costly and seems unavoidable but there are means and processes with which we can reduce the occurrence of defects. I am a big supporter of review process. In my opinion, number of defects in the system can be reduced if there are reviews in each stage of development. Also, I think there must be more focus on better reviews in the preliminary stages like design. What do you think about this? It would be great if you can share the particular mean or process that has really helped you in reducing defects.

Monday, July 29, 2013

Porting code : Does it help?

You work in a project that manages (create, enhance and maintain) a large software product. Your manager comes to you and ask you to add a new software feature for this product. He has given you complete freedom in deciding on how to proceed. You know that the same software feature is already available in another OS as open source with favourable licensing or from a company as closed source. You can port it instead of implementing it yourself. So the critical question here is should you go ahead and port the code or implement this yourself?

In last few years, I have ported couple of large features while reviewed few large features that were ported by others. There were few very specific reasons why we decided to port a specific feature (I think most of you who decides to port a particular code will be having something similar):
  1. Porting the feature will save ample amount of time and in turn money.
  2. We will get a well tested code and we will be bringing in less number of bugs into our code base (which we know is a better code).
  3. Community (or the company if you have bought the code base) will provide bug fixes and enhancements which can be ported easily so we as such do not need to worry about them.
Now when I look back at some of these ported features, I feel that it would have been better to implement them ourselves instead of porting them. Here are the reasons:
  1. In at least one of the cases, the code we ported was not modular enough and did not gel well with our code base. We end up spending lots of time in creating or extending existing APIs in the ported code.
  2. In at least one of the cases, we needed to port only one part of the feature but we had to port the whole code and later we realized that there is no way to just compile that part of the feature. It took us lots of time to finally get what we wanted.
  3. One of the feature had interaction with operating system and management systems like CLI. These interactions have been standardize in our product. It took us some efforts to make ported code use these standardized interfaces instead of what it was using before.
  4. In couple of cases, we decided to own the code after porting as we had made changes so we could not rely solely on bug fixes from the actual source.
  5. As the code was not writing internally, none of us knew the whole code which brought in unknown to our code base. If any bug is seen, there was always a doubt that it is coming from the ported code. In any case, everybody thinks that whatever they have written is almost a bug-free code.
Please note that I am not saying porting is bad. What I am trying to suggest is that do not decide to port just because the code is available. Look at the following things before you make a decision:
  1. Is the code modular and structured enough that you can integrate it with your software without creating too many new interfaces?
  2. Are you looking to port only part of the code? Is this part big enough to justify porting?
  3. Is it possible to port the code without making too many changes in the code? This means if you are making too many changes then you may not be able to take bug fixes and enhancements just like a patch. Also in such a case, you must look at the whole code and after porting, you have a similar confidence as if you have written it yourself.
  4. Can your management system support be added in the ported code easily?
  5. Is the code you are porting is readable and maintainable? Can your team be able to maintain this without the outside help?
I am sure a lot of you would have done this in the past and will do it in future as everybody today talks about re-usability. But my suggestion is that before you actually take the plunge, do ask yourself, will this porting really help?

Also some of you would have done some porting in your software engineer life so far, please do share your experience, views and opinions on this.

Thursday, July 4, 2013

Code review : A necessary evil


Do we really need code review? Ideally speaking, we don't. But idealism is seldom practical. If people write their code properly without any bugs, there is no need for code review. But is this humanly possible? Naah!

I have talked to my friends who are working with different OEM companies about code review in their projects. Most of the responses fall under three categories:
  1. There is no code review as everybody is pretty good with the code. Also, a lot of regression testing takes care of the bugs.
  2. There is code review but not many people takes it seriously.
  3. There is code review and everybody takes it very seriously. For bigger code changes, multiple reviewers review the code.
I have been part of multiple projects where we maintained larges software for various clients and we have always been in the third category. So I think I am not qualified to outline the advantages of no code review but let us look at what does a strict code review brings to the table:
  1. A reviewer is a different person. He thinks about code differently. So he brings in a different perspective when looking at someone else's code. He can look at the modularity, scalability and maintainability of the code as a neutral person. Believe me this has really helped me (and our projects) a lot.
  2. Developers are usually in hurry. They need to finish the current task at hand and move to the next task. A code review helps in establishing that a feature has been implemented as stated in the requirements.
  3. Developers are usually bad unit tester. During unit testing, they tend to miss the negative test cases or specific scenario test cases. A reviewer during the code review can identify some of these negative and specific scenarios for the developer to test. This increase the overall reliability of the feature.
  4. If you identify the code reviewer smartly, you can use this exercise to train new people in code as well as code review.
All these reasoning looks pretty good but are there any side-effects? Yes, there are.
  1. I have witnessed first hand that a some review comments late in the review cycle can create havoc. Developer tries to carry out the change fast as he needs to commit his code and usually forget to handle some special cases which he had taken care in the first phase.
  2. A similar situation comes when code review process gets delayed for some reasons. In couple of weeks, developer may not remember why a code is written the way it is written. So when a comment is given in that part of the code, developer is not sure what to do and might end up breaking his own code/logic which was most probably correct.
  3. A developer will have to allocate 20% of total development time for review.
There seems to be both pros and cons of doing code review. So what is my take?

I think I will go with the title, 'Code Review is a necessary evil'.

To learn something more on this topic, I would request people who have followed 'No code review' policy to please mention the advantages and disadvantages they see with 'No code review' policy. May be then, we can debate on what makes more sense.