The term 'debugging' came from the days when computers where the size of rooms and insects would get caught in the components and they would 'literally' have to debug the computer. The term just stuck!
Today the term just means 'fixing an issue in a program’. typically, the code. for example, if I write and compile a C program and it crashes, or doesn't work as expected then it is said to have a bug, and is in need of debugging (the process of finding and fixing the issue(s)).
There are three basic type of 'bugs' that a program can have, syntactical, semantic or logical.
Syntax and semantics are two sides of the same coin.
Almost every line in a source file is a command for the computer to execute (statements). The syntax and the semantics are instructions and the details of how to carry out those instructions.
the syntax is <type> identifier <assignment operator> <mathematical expression>
In plan English, we want the computer to create an int object and assign the identifier direct access to the address, then we want the CPU to do the calculation of 5 / 2 and assign the result to the identifiers address.
Syntactically and syntactically the statement is fine, provided we are only interested in the integer value, but what if when we divided 5 by 2 and we wanted 2.5? Suddenly, we have a semantic problem, we are expecting 2.5 and only getting 2 (due to truncating when dividing two int types).
Now it's important to note, that only syntax errors will give us a compile error and is probably the easiest bug to get rid of because compilers will often point out the file name line and also underline the syntax error.
Semantics is a little trickier, because the compiler assumes you understand that truncating occurs when dividing two integer types.
Then there is the logical error, this is typically down to logical conditions in if, if else, for, while, do etc.. Something has gone wrong with a logical condition and the program has gone down the wrong branch in the code.
Sometimes, It won’t be clear as to whether or not you have a semantic error or a logical one.
let’s assume you have a huge project and let’s also assume that you do not understand what truncate is or does. (if you don’t, then even better).
You write a basic program as follows:
Code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i = 5 / 2;
if ( i == 2.5)
{
printf("I = 2.5\n");
// Do stuff
}
return 0;
}
You need the ‘if conduction’ to evaluate to true. 5 / 2 is 2.5 right? But, you can’t figure out why the print statement inside the if condition isn’t displaying! Is this a logical error or semantics? How do I find out how to fix this bug!
Well, I’d always start with adding a printf() debug statement before the if condition.
now we have:
Code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i = 5 / 2;
printf("DEBUG : i's value is %d\n", i);
if ( i == 2.5)
{
printf("I = 2.5\n");
// Do stuff
}
return 0;
}
output is:
Code:
Lawsons-iMac:my_c_projects lawson$ gcc problem.c
Lawsons-iMac:my_c_projects lawson$ ./a.out
DEBUG : i's value is 2
Whoa? Why is it 2 and not 2.5? Let’s look on Google. “C dividing 5 by 2”, first search result: c - Why dividing two integers doesn't get a float? - Stack Overflow
Ah-ha! I need to use a float, not an int, and I need to add .0 so 5.0 / 2.0!
Code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
float i = 5.0 / 2.0;
printf("DEBUG : i's value is %d\n", i);
if ( i == 2.5)
{
printf("I = 2.5\n");
// Do stuff
}
return 0;
}
output
Code:
problem.c:8:38: warning: format specifies type 'int' but the argument has type
'float' [-Wformat]
printf("DEBUG : i's value is %d\n", i);
~~ ^
%f
Ops, syntax error! Looks like the problem is in my problem.c source file on line 8! It is saying something about I’m formatting using an int but giving it a float. Oh, cool have a wiggly line under the problem part and a carrot (^) pointing to the issue, oh it has even given me what I could change it with. so %d need to be %f.
final change.
Code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
float i = 5.0 / 2.0;
printf("DEBUG : i's value is %f\n", i);
if ( i == 2.5)
{
printf("I = 2.5\n");
// Do stuff
}
return 0;
}
output
Code:
DEBUG : i's value is 2.500000
I = 2.5
I hope this example helps you to understand about debugging. You're going to be doing a lot of it the more you program.
The process I tend to follow is this:
Find out what type of bug you're dealing with? Normally, i use printf()s throughout my code to keep an eye on what values are stored in a variable.
Narrow it down and if I don't understand why it is happening it is time to hit up google to find out why I'm having this issue and get clues as to how to fix it.
Once you isolate the issue, open up a new project and simplify the code until the issue is very clear.
if you follow those steps, and you get really good at debugging. Sometimes it is enough to break out a pen and a piece of paper and jot down what you think might be the cause of the issue, followed by possible fixes, start there and systematically test your theories. This will make you much faster in solving and identifying problems.