ooblick.com
0% trans fat!
The Ooblick Institute for Tenure Research presents

Compilation Errors Can Be Your Friends

Let's say you have a data structure:

        struct Foo {
	    short flags;
        };

At some point, you decide that a short is too small, and want to use a long. Now you have to find all of the places in your code where you use Foo.flags, and fix anything that your change might have broken. What's the best way to do this?

Let the machine do the work for you.

Don't just change flags's type, change its name as well:

        struct Foo {
            long newflags;
        };

Then recompile your program. The compiler will flag every line where you use Foo.flags as an error, forcing you to examine each place where you use it and fix it as necessary.

If you wanted the field to be called flags, then once you've finished correcting for the fact that newflags is a long, just change its name back, and repeat this technique in reverse.

Cascade Effects

Occasionally, you will find that you need to make further changes, e.g.:

        struct Foo foo;
        short temp_flags tf;

	tf = foo.flags;

Here, tf (and everything that references it) needs to be modified as well. So just rename the variable tf to new_tf and recompile. Again, the compiler will find all instances where that variable is used.

Function Arguments

This technique works with function arguments, but you have to be more careful. If you're changing

        int myfunc(int arg)

to

        int myfunc(void *arg)

then you must make sure that the header file where myfunc() is declared (you did declare myfunc() in a header file, didn't you?) is a full prototype. That is, the header file should now say

        extern int myfunc(void *arg);

and not

        extern int myfunc();

Advantages

Disadvantages and Limitations