Title: Updated 081107
1Debugging
2Debugging
- The ability to find errors is just as important
as creating a program. - Being capable of efficiently track errors is an
important skill to learn. Debugging is just as
much a logical process as the rest of this course.
3Compilation Errors
- When you compile a program, the compiler is able
to detect syntax errors and potential programming
errors (i.e. warnings). Double clicking on an
error, will produce a marker where the compiler
believe the error is (it is often somewhere
nearby). It is always best to fix the first error
listed, re-compile, and then fix the next error.
This is because fixing one error may impact other
errors.
include ltiostreamgt using namespace std int
main() int a, b, c a 3 b 2 c
ab cout ltlt "a " ltlt a ltlt endl ltlt "b "
ltlt b ltlt endl ltlt "c " ltlt c ltlt endl
system("pause") return 0
Note that in this case the compiler highlights a
line of code but the error is in the line before!
13 C\Adrian\Teaching\08-09\ecor1606f08\temp\debug
.cpp expected ' before "cout"
4Compilation Errors
- In many cases, the compilation errors that are
reported do not make sense and/or the location
indicated is incorrect (the compiler tries to do
its best). You can still use the error as an
indicator on where to start looking.
include ltiostreamgt using namespace std int
main() int a, b, c a 3 b 2 c
ab cout ltlt "a " ltlt a ltlt endl ltlt "b
" ltlt b ltlt endl ltlt "c " ltlt c ltlt endl
system("pause") return 0
Here there are extra semicolons
The error suggests that you need something before
the ltlt. While you could add a cout on the
highlighted line, what you wanted to do was
remove the semicolon on the previous line.
14 C\Adrian\Teaching\08-09\ecor1606f08\temp\debug
.cpp expected primary-expression before 'ltlt'
token
5Compilation Errors
include ltiostreamgt using namespace std int
main() int a, b, c a 3 b 2 c
ab cout ltlt "a " ltlt a ltlt endl ltlt "b "
ltlt b ltlt endl ltlt "c " ltlt c ltlt endl
system("pause") return 0
In this case we are missing the first brace but
the errors that are reported do not indicate
this. This reinforces the point that the compiler
errors do not always provide the correct
indication of what is wrong with the program but
may indicate where to start looking. Plus there
are a large list of errors reported, even though
there is only one small mistake.
7 C\Adrian\Teaching\08-09\ecor1606f08\temp\debug.
cpp expected init-declarator before "int 7
C\Adrian\Teaching\08-09\ecor1606f08\temp\debug.cp
p expected ,' or ' before "int 9
C\Adrian\Teaching\08-09\ecor1606f08\temp\debug.cp
p expected constructor, destructor, or type
conversion before '' token 9 C\Adrian\Teaching\0
8-09\ecor1606f08\temp\debug.cpp expected ,' or
' before '' token 10 C\Adrian\Teaching\08-09\e
cor1606f08\temp\debug.cpp expected constructor,
destructor, or type conversion before '' token
6Compilation Errors
- In complicated programs it is sometimes difficult
to determine where your compilation error is
occurring. In some cases, it is useful to comment
out large portions of code (essentially deleting
the code) to isolate where the compilation error
is occurring. - While the following example is simplistic and
relatively obvious, this technique is definitely
useful in complicated program.
7- include ltiostreamgt
- include ltcmathgt
- using namespace std
- int main()
-
- double x1, y1, D1, x2, y2, D2, distance, R1,
R2 - while (true)
- cout ltlt "Enter x1, y1, and D1 (make D1 zero
to terminate) " - cin gtgt x1 gtgt y1 gtgt D1
- cout ltlt "Enter x2, y2, and D2 (make D2 zero
to terminate) " - cin gtgt x2 gtgt y2 gtgt D2
-
- if (D1 0 D2 0)
- break
-
- if (D1 lt 0 D2 lt 0)
Here we are missing the if, which may not be
obvious from the error message (which suggests
adding a semicolon!). It may also be difficult to
find due to the complicated nested-if.
32 C\Adrian\Teaching\08-09\ecor1606f08\temp\debug
.cpp expected ' before '' token 34
C\Adrian\Teaching\08-09\ecor1606f08\temp\debug.cp
p expected primary-expression before "else"
8- include ltiostreamgt
- include ltcmathgt
- using namespace std
- int main()
-
- double x1, y1, D1, x2, y2, D2, distance, R1,
R2 - while (true)
- cout ltlt "Enter x1, y1, and D1 (make D1 zero
to terminate) " - cin gtgt x1 gtgt y1 gtgt D1
- cout ltlt "Enter x2, y2, and D2 (make D2 zero
to terminate) " - cin gtgt x2 gtgt y2 gtgt D2
-
- if (D1 0 D2 0)
- break
-
- if (D1 lt 0 D2 lt 0)
Commenting out part of the code shows that the
rest of the program does compile successfully and
that the error is likely in the commented portion.
9- include ltiostreamgt
- include ltcmathgt
- using namespace std
- int main()
-
- double x1, y1, D1, x2, y2, D2, distance, R1,
R2 - while (true)
- cout ltlt "Enter x1, y1, and D1 (make D1 zero
to terminate) " - cin gtgt x1 gtgt y1 gtgt D1 gtgt endl
- cout ltlt "Enter x2, y2, and D2 (make D2 zero
to terminate) " - cin gtgt x2 gtgt y2 gtgt D2 gtgt endl
-
- if (D1 0 D2 0)
- break
-
- if (D1 lt 0 D2 lt 0)
Here the problem is the use of endl in a cin
statement and what a error message! In such cases
it may be worth while to write a small program
that examines just this line of code to see how
it is causing difficulties (and that it is indeed
this line of code that is in error).
12 C\Adrian\Teaching\08-09\ecor1606f08\temp\debug
.cpp no match for 'operatorgtgt' in
'(((stdcin)-gtstdbasic_istreamlt_CharT,
_Traitsgtoperatorgtgt with _CharT char, _Traits
stdchar_traitsltchargt(((double)(x1))))-gtstd
basic_istreamlt_CharT, _Traitsgtoperatorgtgt with
_CharT char, _Traits stdchar_traitsltchargt((
(double)(y1))))-gtstdbasic_istreamlt_CharT,
_Traitsgtoperatorgtgt with _CharT char, _Traits
stdchar_traitsltchargt(((double)(D1))) gtgt
stdendl'
10- include ltiostreamgt
- include ltcmathgt
- using namespace std
- int main()
-
- double x
-
- cin gtgt x gtgt endl
-
- cout ltlt "x " ltlt x ltlt endl
-
- system("pause")
- return 0
-
While this gives the same error, there is
certainly a lot less code to examine, and the
error may be easier to find (especially when you
compare it against the crib sheet)
11 C\Adrian\Teaching\08-09\ecor1606f08\temp\debug
.cpp no match for 'operatorgtgt' in
'(stdcin)-gtstdbasic_istreamlt_CharT,
_Traitsgtoperatorgtgt with _CharT char, _Traits
stdchar_traitsltchargt(((double)(x))) gtgt
stdendl'
11Logical Errors
- Compilation errors are often easy to find and
fix. It is relatively easy to get a program to
compile compared to getting a program to actually
work the way you want it to work. - Logical errors refer to mistakes in your program
that cause it to behave in a manner different
from what you want (i.e. the program is giving
you the wrong result). - In complex programs it is difficult to find this
errors. A useful method of tracking these errors
is to use debug outputs. These outputs can be
used to find out what lines of code are being
executed and what the current value of certain
variables are.
12Logical Errors
In this program we are trying to prompt the user
to enter a number until a non-negative value is
entered. By mistake a continue statement was used
instead of a break. This problem will not result
in a compilation error.
- include ltiostreamgt
- include ltcmathgt
- using namespace std
- int main()
-
- int x
- while (true)
- cout ltlt "Enter a value of x "
- cin gtgt x
- if (x gt 0)
- continue
-
- cout ltlt "Invalid input" ltlt endl
-
Enter a value of x -3 Invalid input Enter a
value of x 4 Enter a value of x
It is confusing this error because the program
successfully deals with negative values and does
not indicate an Invalid input for positive
ones, but does not exit the loop.
13Logical Errors
- include ltiostreamgt
- include ltcmathgt
- using namespace std
- int main()
-
- int x
- while (true)
- cout ltlt "Enter a value of x "
- cin gtgt x
- cout ltlt "DEBUG x " ltlt x ltlt endl
- if (x gt 0)
- cout ltlt "DEBUG Inside the if
statement!" ltlt endl - continue
-
Enter a value of x -3 DEBUG x -3 Invalid
input Enter a value of x 4 DEBUG x 4 DEBUG
Inside the if statement! Enter a value of x
This debug line will ensure that the value of x
we read is correct
From testing we can see our if statement is
indeed correct but we did not break out of the
loop as we wanted to.
This debug line will ensure that our if statement
is correct or not.
14Logical Errors
- Adding debug statement can be of particular
important for complex programs with nested loops
and functions. Look at the following pieces of
code to see how various debug statements are
implemented.
for (i 0 i lt 10 i) cout ltlt "DEBUG
(before j for loop) i " ltlt i ltlt " j " ltlt j
ltlt endl for (j i j lt 10 j) cout ltlt
"DEBUG (in j for loop) i " ltlt i ltlt " j " ltlt
j ltlt endl x ij cout ltlt "DEBUG (after j
for loop) i " ltlt i ltlt " j " ltlt j ltlt endl
int a_func(int x, int y) int z cout ltlt
"DEBUG Enter a_func x " ltlt x ltlt " y " ltlt y
ltlt endl z y --x cout ltlt
"DEBUG z " ltlt z ltlt endl cout ltlt
"DEBUG Exiting a_func x " ltlt x ltlt " y " ltlt y
ltlt endl return z
15Functions
- When you are debugging code with functions, it is
often useful to test your functions independently
from the rest of the code. One of way of doing
this is to comment out the code in the main
function and make simple calls to the function
you are testing. - The following code (which is spread over three
pages) is for a program that can compute the
Taylor series approximation for the function
sin(x). A portion of the code is commented out to
enable testing of the kFactorial function, which
computes the factorial of a number. The main
program has also been modified so that particular
values of the kFactorial function can be tested.
16- include ltiostreamgt
- include ltcmathgt
- using namespace std
- const double PI 2.0asin(1.0)
- int kFactorial(int k)
- double f(int k)
- double taylorApprox(double x, int n)
- int main()
-
- cout ltlt kFactorial(1) ltlt endl
- cout ltlt kFactorial(2) ltlt endl
- cout ltlt kFactorial(5) ltlt endl
- cout ltlt kFactorial(20) ltlt endl
The entire main code is commented out and a
simple calls to kFactorial. Look at the function
first and see if there are any issues that you
see. Then try this code! Does the function work?
17- if (x lt -PI x gt PI)
- cout ltlt "Input x must be between -PI and PI."
ltlt endl - continue
-
- break
-
- sinx sin(x) // actual value
- // display the actual value
- cout ltlt "sin(" ltlt x ltlt ") " ltlt sinx ltlt endl
- while (1)
- p taylorApprox(x,order)
- error fabs(p - sinx)
- // display the current Taylor approximation
- cout ltlt "P_" ltlt order ltlt "(" ltlt x ltlt ") " ltlt
p ltlt endl
18- int kFactorial(int k)
-
- int i
- long int k_fact 1
- // no need to start at i 1
- for (i 2 i lt k i)
- k_fact i
-
- return k_fact
-
- double f(int k)
-
- k k4
- if (k 0)
- return 0.0
19Simplifying/Reducing the Program
- When you are facing a large number of inputs or
large arrays (you will learn about arrays later),
it is often useful to reduce the number of inputs
or the array size to make the program
easier/faster to debug. For example, the
following program is supposed to find the largest
number entered out of a series of 1000 numbers.
include ltiostreamgt include ltcmathgt using
namespace std const int NUM_INPUTS 1000 Int
main(void) int highest, curInput, i cout ltlt
"Enter a number " cin gtgt highest for (i
0 i lt NUM_INPUTS i) cout ltlt "Enter a
number " cin gtgt curInput if (curInput gt
highest) highest curInput cout
ltlt "Highest number entered is " ltlt highest ltlt
endl system("pause") return 0
Here it would be prudent to change NUM_INPUTS to
10 to ensure it works. This error becomes
feasible to find.
Will prompt the user 1001 times, which is not
necessarily obvious unless you run the program
testing this with 1000 entries it would take
quite a bit of time!
20Infinite Loops
- A common problem is when you have a loop but are
never able to exit the loop. An example is shown
below. Adding the debug statements that are shown
would quickly reveal where the problem is!
include ltiostreamgt using namespace std int
main(void) int x, n 0 cout ltlt "Enter a
value for x " cin gtgt x cout ltlt
"The program will determine how many times you
need " ltlt endl ltlt "to double x to have a
value greater than 1000." ltlt endl while
(true) // cout ltlt "DEBUG1 x " ltlt x ltlt
endl if (x gt 1000) //
cout ltlt "DEBUG2 x " ltlt x ltlt endl
continue // should be a break x
x2 n cout ltlt
"You need " ltlt n ltlt " doublings to get
a value greater than 1000" ltlt endl
system("pause") return 0