In a previous blog post, I talked about bug negative verification. I also said that debugging should be avoided as much as possible.
That is true, debugging is mostly a waste of time. You spend a lot of hours trying to figure out why what you yourself wrote doesn't work as it should. After you solve the bug, you don't have a new feature, there is no prevention that you will make the same mistake in the future and you might have to redo the same wasteful debugging process you just did. Right? Well, not exactly.
A good philosophy to adopt is, can I do something so the same kind of bugs won't reappear in the future? If you invest some time, after solving the bug, to figure out how to prevent future similar bugs from happening you might learn or gain something from the bug. That is why a bug is an opportunity to learn how to prevent similar bugs in the future.
For instance, a buffer overflow is when you are accessing an array beyond its allocated size. In c++ it would be doing something like this:
a = 12;
If your program is doing weird things, you might eventually capture this bug. But its obvious it is better to use an array that is safe. Such as, an array that check if the index provided for cell access is within the boundaries of the array. If its not, it will report a run time error and let you know you did something wrong.
However, things are not always as simple as in the case of the array. Sometimes its not clear how you can prevent certain bugs. Lets say you have a game with medieval weapons such as swords and daggers. You want to give the dagger a power of 2 and the sword a power of 3. You gave the sword a power of 3, but you accidentally gave the dagger a power of 4. This is a bug, even though nothing will crash. It would be very difficult to prevent this kind of bug, but I can think of ways that would help catching this bug early.
Another concrete example is GPU shaders. You can write a shader in some high level language such as HLSL for directX. These shaders often have global parameters you can set through your program. I had a bug in a shader that it didn't draw what I meant for it to draw. I then began debugging. First I checked if the color texture was really passed to the shader. Then I checked the normals in the vertex data and etc. I finally found that I forgot to set one of the global parameters of the shader. I wasted an hour or two to figure out this bug. A way to prevent this bug is to keep track of which parameters are set before each draw call, and report an error if not all the parameters were set.
However, you sometimes don't want to set all the parameters in a shader, so what is the right choice?
I would say its a good habit to do some thinking after solving a bug, and not immediately move on to the next task. Why this bug happened? How I solved it? Did I really solve it? How can I prevent similar bugs from happening in the future? Should I prevent similar bugs in the future or is it not cost effective and having this kind of bug from time to time is acceptable?
Last but not least, you need to take what I said with a grain of salt. This is something that worked for me, from my own experience under certain conditions, but you don't have to do exactly the same. Its not formal anyway, because you can't 100% formalize programming. Its an advice, not rules or a recipe to follow blindly.