0:02

Drew has given me a program called rotate,

and he told me there's a bug in it.

So let's look at the program and see what it's supposed to

do and then see if we can find the bug.

Here in rotate.c, let's look at the main.

Main calls testRotate.

And what this program is supposed to do is take a point (1,0) or take a point such as

(1,0) rotated by an angle such as 90 and then see what point is the output.

Here in testRotate, we're calling it with

(1,0) and 90 so we expect the rotated point to be (0,1),

and the function testRotate will let us know if we're getting the output we expect.

So let's look at testRotate.

It takes an x and y value,

a number of degrees to rotate it by,

and then compares it to the expected value.

Here, we have two assert statements.

This one that compares the x value to what's

expected and this one that compares the y value to what's expected.

And this function calls rotate with a point and a number of degrees.

So let's look at this function rotate.

Here, it does the work of the rotation by calling these trig functions cosine and

sine that are included in the header, math.h.

So let's run this program and see what the bug might be.

Rotating (1,0) by 90 degrees,

that was our first test case.

Assertion failed, and the assertion that failed concerns the y values.

So we're having trouble transforming the y value to get the one we expect.

Back in Emacs, we can run the debugger to see what the values are in this program

as it runs and see if we can find where it's doing something we don't expect.

So I'll do meta-x gdb,

run it default, and once you start the program,

it'll stop just after it enters main.

And in this program,

there's probably no problem in main.

We're just calling testRotate.

In testRotate, the work is really being done by the function rotate,

and we can see that two lines later,

this assert here is what's failing.

So somewhere in this function rotate,

we're probably doing something we don't expect.

So one way to investigate that is to set a breakpoint just inside the function rotate.

You can also set a breakpoint on a line number but, here,

I know which function I want to look at,

and then I'll continue running.

2:53

Change buffers.

I want to look at the program.

Okay. So here I've set a breakpoint on the line just inside the function rotate,

and I'm about to execute this command that changes p.x and rotate it by 90 degrees.

I'm very interested in the values of p.x and p.y,

so one thing I can do is display their values.

And that way, each time I advance the code,

it'll tell me what the values of those are.

And I can do the same thing for p.y.

(1,0). Those are the input values.

So at this point in the program, that's what I expect.

So I will step,

and I've stepped into sine. That's not what I meant to do.

So if you enter a function that's not useful to you,

you can finish and go to the end of that function.

And then I will advance to the next line.

So, now, the values of p.x and p.y have changed.

p.x is something times 10 to the negative 17th,

very, very small, so close to 0.

And we're expecting the output to be (0,1).

So that value of p.x makes sense.

We're okay with that. Advancing past the next line,

and we get a value for p.y,

that's also very small.

That's not what we expect. We're hoping to get the point (0,1) out of this.

So, let's see why this calculation on p.y might not be giving us the answer we want.

The input value of p.x is one,

sine of 90 is one,

so that part should be one,

plus input value of p.y is zero,

times the cosine of 90 is zero.

So this line should say 1 plus 0 but, somehow,

it's giving us the answer 0 instead. Can you figure out why?

Here, we're using p.x,

but we're expecting it to be the value we had on input, 1.

However, we've changed its value on the previous line.

So how can we change that? We'd like to preserve the input values of x and y.

And one way to do this is to create a new point t called answer,

and then we will, instead,

assign values to the answers x and y.

And then we will return our answer.

So let's save that and compile,

and then let's run gdb again.

We're stopping at that same breakpoint.

Once again, let's display p.x and p.y.

They're (1,0) on input. That's what we expect.

Advance to the next line.

p.y and p.x are unchanged. That's the behavior we want.

Let's print the value we just assigned answer.x,

close to zero, good.

Advance it again.

And then print the value of the answer.y, 1.

That's also what we expect.

So I think we fixed our program.

Let's go ahead and clear the breakpoint in this function and run it until the end.

So here's the output from our program.

It's gone through all of these test cases,

rotating (1,0) by 90 and got (0,1). That's what we expect.

Rotating (0,1) by 90 and getting (negative 1,0),

also what we expect.

You could do some of these in your head and make sure they're right.

But the important thing is that none of our assert statements failed.

So it looks like we've fixed our program,

and we can quit the debugger.