Friday, October 5, 2007

Don't Change Behavior

This is code maintenance 101... when you are working on a library that has more than 1 user you cannot change a function's behavior without repercussions.

A function has things it requires, and things it promises if the requirements are true.

You should not change these in such a way that would cause any existing code using the function in a supported way to change behavior.

For example:

// requires that i is non negative, less than len and str is not NULL.
// promises returns str[i]
getchar(char *str, int i, int len);

This is the only thing this function currently promises.

So you could add functionality for when i is negative and not break existing code.

It would be nice if all of our code had unit tests that ran whenever a change was made, but most of us don't, especially people maintaining old old code, so be smart with your function maintenance.

If you need to do something that YOU think is a bug fix, but it changes behavior, you better be damn sure that everyone using that function agrees that it is a bug, and that your fix will not break their workarounds.

The nice thing is there are ways around this even if you don't have a pristine unit test framwork.

What you must have is a pristine integration setup, preferrably continuous integration. This way you can make your bug fix and CHANGE THE FUNCTION NAME slightly, which in the world of compiled languages will cause build breakages at all points that reference that function and you or the code maintainer can look at each instance and determine if it will behave as expected.