 We are in office hours on November 17th, and we have a question about how to approach the—oh, it's not this problem—how to approach the problem of—what is this?—problem 4 on the fall 2015 actual midterm. It is a—yes. So the question says, consider the following code and see syntax, and we can see there's a program here with three functions, which looks delightful. And then at the bottom it says, draw the stack—draw the program stack at the first execution of location one, specified as a comment in the function main. So that tells us we now know we have to—we want to see what happens—what does the stack look like when we hit location one? Right? Cool. Well, we should read everything, right? We shouldn't just start executing things. We need to read it. So we say, label on the stack all function frames, and inside each function frame—that should say frame—and inside each function frame, label the parameters to the function, the value of those parameters, the function's local variables, and the value of those local variables. Also, the important thing is that's why it's in italics. You do not need to follow precise C-deckle calling convention. So what this means is that you don't have to—we know based on C-deckle that when we call function bar on the stack, we will have C-B-A like this. We're saying—we're relaxing that restriction and saying we don't have to have it exactly like that. As long as we have all of the parameters, that is the important part. Then the next important thing is we've learned all kinds of crazy scoping rules and pass-by semantics. So this one says we assume static scoping and we're assuming pass-by value semantics. In class. In class for all the class examples we're going to assume for the runtime environment questions. How to approach this? We've got to draw a stack. As we've said, the only proper way to draw a stack is starting at the top and going down. Our stack is going to start here. First question. We see we have global variables x and we have this definition of a function main. Is x going to be on our stack? Do they? Neither. They are globally allocated. The compiler just chooses a location for x and puts x somewhere else. This is why we have the three types of variable allocations. We have global variable allocation which is stored in a fixed location and is always there. It is allocated when the program is created. It is never deallocated and those locations never move. If you print out the location of x, the address of x throughout the program, it will remain constant. It may not remain constant through each run but that's something else. Global variable is going to be global so it's not going to be on the stack. Stack allocation is done automatically when a new function is executed and when we get into a new scope, so a new function frame and stack allocation is automatically deallocated. So when we leave a scope, we automatically deallocate that. Exactly. Contrast that with the heap which the programmer has to manually say, give me memory, allocate me memory on the heap and that is good until the programmer says, I'm done using this memory. Feel free to reuse it. I'm freeing this memory. Cool. We don't draw x on our stack. Our stack wills. Sorry, my position. I need to make it like this. Otherwise, for people who are watching at home, I just moved the mouse so I could actually draw a straight line. Sorry. Okay. We have our stack. When our program first gets called, what function is on the stack? What did you say? What's the first function that executes? Main. Main. This is where we start executing. This is a function just like every other function. Main has a function frame. So main is going to have some function frame. And so we will have, and what do we have to draw? We have to draw the program frame, label on the stack, label all the function frames with the name of the function. Inside each function frame, label the parameters to the function and the values of those parameters. So what parameters are there to main? Parameters. I. That's good. Okay. And what's the value for I? We don't know. Main just got called. There's going to be some value in there. We don't know what it is right now. And then how many local variables are there for main? Cool. So we have one local variable, baz. What's the value of baz? We don't know yet. Exactly. And then we have c. What's the value of c? It doesn't really matter how you draw the array, but we know there's some array of zero, one and two here, right? Cool. And this is the function frame of main. Wait. Now we go. We say, if x is equal to 100, what's the value of x? 10. So we have is x equal, sorry, is x equal to 10? So then we do go into here and we output what? I is 20. So I is here. So we can say there's some global x. We can keep the value of x up here. We can say it was 10. Now it's being changed to zero. And I is now 20. So now we have a value for I. It's 20. Cool. And then we print something out. Do we care about what we print out? Exactly. The question does not say what is it output? So we don't care about that. I'm going to turn the question. But that's because I like to have these actually execute. Okay. So then we get to this branch, right? This is not an if else. This is an if. We say, if I is greater than zero. So is I greater than zero? Yes. Then do what? Now we call function bar. We call function bar. When we call function bar, what's going to happen? We create another function frame. Stacks grow down. So the stack pointer pushes down now. Yes. So right now, so the nice thing about this question, and this is why, you know, we're not asking C decal semantics. We're not saying it has to look a certain way. We're not saying, give me the stack pointer and show me how that's all changing, right? This is at a high level. How, what does the stack look like? So we're going to call bar. So now we have bar. So what parameters are there for bar? A, B, C, right? Cool. So now what are the values here? What are the values for A, B, and C? Those are types. What are the values? C2, which is? Two. Two, which is zero. Cool. All right. Does bar have any local variables? So we have X. Do they have values? Not yet. No. That's why we say the precise C decal semantics doesn't matter. You should, I can't remember how we graded it, but we should have all the parameters before all the local variables, right? That definitely makes sense. So this is the function for bar. Cool. Then we look at the first line. What are we doing? So now X is equal to 21. 21? Are we sure it's not changing this one? Is it going to change this one? No, it's changing a local one, because it's inside of there. Look at that. Got to keep you guessing. Okay. So what happens on the next line? We call a function name. We call a foo. And then what are we going to do with foo? Once foo executes. So when foo finishes, then what's going to happen? Then you call me. Yes. Then the return of foo is getting passed to the function main. Well, it makes sense, but I didn't see that until you said it. Well, we have a function call in here, right? The things we have to evaluate. We want to call main, but first we have to call foo. So we get the return value of foo that we're going to pass into main. So we're going to call foo. So now how does our stack change? We make another function frame on the bottom of our stack. For foo. So how many local variables does it have? It has two parameters. These are parameters, sorry. Alpha, beta. And how many local parameters? Local variables, sorry. One. A. Cool. So then what is the value for the parameter alpha? That's in C and B. C, which is? C is 20. And B is? Zero. Zero. Cool. And then we say A is equal to 10. So what did that change? Okay, quick question. What? It doesn't cause a compiler, I can't remember. Why? Char, beta, B. In alpha takes a char. C is a char. Int, C hears an int. Yeah. It's tricky. You're mixing it up. Yeah, char, char, int. Yeah. Roll with the punches. Okay, so what happens here? So A is what? How does this line change things? It's a local A's. Local A is 10, boom. And then what about this one? That is now global X. The global X changes to what? Negative 20. Now what happens on the next line? Now we return negative 20 to me. That's, um... We what? No, no, no. You return... Send in negative 20. So then what happens on our stack? Well, yeah, you call the main function. But you pass in negative 20. But now I'm a bit confused now. So this is? That's foo. Foo? Cool, now what happens? I don't know, dude. Does the stack pointer jump up to main now? You're gonna have two new mains, right? Main is a function just like anything else. When we have recursive functions, if we had bar calling bar, we will just have new function frames of bar. So now you build another frame for main. Now we build another frame for main. Do you need this empty? No, that's just me. I drew too many, and I don't want to change it. So now we know from our other one it should be in the same order, right? I, Baz, and C. Now the question is what is... So what's the value for I? So I is the parameter to this invocation of main. That's negative 20. Negative 20, cool. And now we know this thing is... Main. Right? Except it's 20, not 2. Sorry, negative 20, you're right. Yes. Cool. Okay, so then we have B, Baz is nothing. C is 0, 1, 2. Cool, let me check. Is X equal to 10? No. No, X is negative 20. Okay, so let's get there. Is I greater than 0? No. No. And then where are we? Location. So there we go. No. That's our answer. So where is the... That would take a little while. Actually, that was not quick. That's time for a midterm quick. They had an hour and 15 minutes. Oh, okay. That's like some time. I only have two midterms. 50 minutes. But I was going to add 2. And maybe this is because I haven't seen it in a while. What cases are we using to like pointers like the EAX and EBP and stuff? Like where? Is that at the C depot though? That would be more... That's more like how it's implemented, right? This is more like a question asking you at a high level what does the stack look like? Okay. Those are all X86 registers. We'll have questions with the pointers and stuff. Because that's... I understand that even though I haven't seen it in a while. That actually made sense. But it was more... I'm more confused about pointers. Do we have any... Do we ever have any... With pointers? I mean with the... With the X86 stuff. Because it's basically going through... I would probably not ask you any specific X86 level instructions. That's perfect. I mean you have a practice midterm you have old midterms you can kind of see how that stuff goes. Question. So when we did return main that's when we created the new... Yes, this main. So what about the main... Here? Yes. This is only going to get called when this foo returns. Yeah. So this main will return something eventually. And then when it returns something that's going to get returned from foo and that will get passed into a new invocation of main with that value. So would there be another... another main? Nope, because we have not invoked... Bar will only call main after it's called foo. Oh, okay. I see which one. Right? Because it needs to first call foo for its return value. Yeah. And then after foo... So we know that's completely returned then it would do a new main. And this question is also good because it tests your semantic understanding of code and being able to read code and understand what it should be doing. Right? So it's testing kind of two things. Any other questions on this before I kill the recording? That was perfect. Cool.