 It's 9 a.m.. It's a beautiful Monday morning. Let's get started get right into it I guess we can do project five questions for a few minutes Yes Do you I'm assuming we also need to create a value node for that it just won't have a name Yeah, the name actually As a check the compiler, but I don't think the name is actually ever used by the compiler Okay, right compiler doesn't care about what the IDs are of the value knows it just cares about copying values for one or the other And then as we're so as we use the same variable over and over Exactly, yes, that is the key you want to make sure that every Reference to a value noted at the same variable points to the same value note right that way your assignment statements will be updated Like when you see you have a print statement that refers to a variable that assignment statement will see the same value Yeah, that's the key to this project and I guess I'll reiterate I think I said on the mailing list you should not do any computation of the program in your front end You should not be assigned if you see an assignment statement that says a is equal to four You should not copy four into the value of the value node a that's all done by the back-end compiler Right, you're not executing the program. You're just creating the intermediate representation to the back end can execute A statement list after the no-off node that you attached after the if statement So after an if statement there's another statement that's a no-off statement And so in your in the compiler.c is it running that If statement and when it hits the no-off node, it's skipping onto the next statement It'll be whatever the next statement is after the if statement, so you're creating like a pseudo no-off statement Because you need to make sure that the true branch of the if statement that its last instruction The next of its instruction is that no-off statement so basically if you think of it like a Tree right it branches was on a tree, but it branches right and so the if branch is going to do stuff and Then it needs to come back after it's done doing stuff to The thing after the if statement, so that's why you're creating this This go-to this no-off statement there so that way you set the Last element of the true statement. I'm sorry the last statement in the true statements You said it's next value to be that no-off statement Yes, that's how you have to do it because it do nested because there may not be a Instruction I guess in that case wouldn't matter, but yeah, I think things a lot easier. All right, let's get back to We're calling convention. So just to kind of recap from where we were on Friday the x86 Linux calling convention the seeddeckle When a caller wants to call a function their job is to first push onto the stack the arguments of the stack in right to left order then they're going to push the Instruction the address of this instruction to return to after the function call and it's the job of the function that's being called To save the previous frame pointer onto the stack because we're going to override it Then they're going to create space on the stack for local variables Ensure that the stack is consistent at a consistent location before it's returned and then finally it puts the return value of the Function in the EAX register, so we look at some code So we're going to get a super simple program So this is a function main as a local variable a it says a equal to calling some function call e Passing the values 10 40 and it's going to return a So this function call e is really easy. It just returns a plus b plus one So if you compile this and this is read the disassembly you'll see it looks something like this So obviously this depends on exactly what compiler and using So main first pushes e.b.p. It moves the stack pointer to the base pointer. It subtracts x18 from the stack pointer It's going to move the value hex 28 into ESP plus 4 It's going to move the value hex a which is 10 into ESP It's going to call that function Call e and then it's going to move EAX into ebp minus 4 and then move ebp minus 4 into EAX which seems redundant that's going to call leave and return instruction So some important things that when you're looking at these function calls, so as we saw right every function In the Cdeco calling convention has to do has to save the previous caller's base pointer and it has to create Room on the stack for its local variables So that's what happens in this with the function prologue So this push ebp is storing whoever calls main's base pointer on the stack and Then it's setting up its own stack frame by saying okay, where the stack currently is Set the base pointer to be wherever the stack currently is and Then it's subtracting 18 from the stack pointer, which is creating well hex 18 So it's creating space on the stack for main's local variables. So why is it creating 8 hex 18? What is hex 18 everybody 24? Why 24 is main's local variable size 24 the size of the main's local variable How many local variables does it make now? What's the size of an integer? four bytes How many bytes did it move it down? 24 partly Let's keep that in mind and think about why when we look at the actual We'll step through this to see exactly what's happening We also have the epilogue of the function right so this leave and return so leave does the complete opposite of these first two instructions It sets the stack pointer to the current base pointer and then it does a pop ebp So it restores the save base pointer and this return is the instruction that says Goes back to whoever called main. So it takes the save instruction pointer that's on the stack and starts executing from it So the coli function is pretty easy. It does a push ebp. It moves the stack pointer to the base pointer It moves ebp plus c into eax it moves ebp plus 8 into edx it adds Eax plus edx moves it into eax it adds one to eax and then it pops ebp and then returns So this function two has the same thing so it has an epilogue its epilogue is actually a little different What is it not doing that name is doing? Yeah, so why why didn't so it's this this line is kind of different But why why did it not do that like coli function doesn't has no local variables, right? So it actually doesn't need to create space on the stack for the local variables So it has a prologue and an epilogue The epilogue is slightly different instead of a leave. There's a pop ebp This is just because the fact that it doesn't have to do both of them Okay, so let's step through this to see how it actually works So we have our coli function. We have our main function and When the program is compiled the compiler will tell Will write out exactly in memory where the bytes of these instructions should be So when I ran this it just said that hey Coli starts at 804 83 94 and all these bytes and main starts at 804 83 85 And so let's say before we're executing this the stack kind of looks like this we have some Some very some registers here and so let's say The top of our stack is that fd2 d4 Right, so and we know this because there is the value of fd2 d4 in the ESP register So the fact that's how we know exactly where the stack is When we start executing main do we know exactly what the values inside this base pointer register? depends on the previous program What do you mean? What's the difference? Because it could be the same program right, so Well a let's talk about it's not the previous program every program when it executes Has its own I don't know fresh copy of everything fresh copy of memory programs can't see each other's memory unless you specifically allow them to So this is going the value in here, right? It's gonna be whoever called main, right? So May think like well why but main is the start of our program, right? Who would ever call me? Yeah, so it's actually libc has to do a bunch of so when you call libc function it dynamically links to that File and that code at runtime so a bunch of things happen to set up your program to be executed You can actually write if you write this the assembly yourself you can say start executing it main And it will work Yeah, it'll work, but normally when you compile a program there is some function that calls me If you do the disassembly you can look and kind of see all that stuff But we don't know what it is. We just know it's something right? We know that there's some value in there and then we know that The instruction pointer when main is gonna start executing points is that 80483 a5 We don't really know anything about the base pointer except Well, we don't know what it is, but we know it should be above our current stack pointer Right because that there's some frame up else in the stack and main is getting called So main needs to make its function frame So the first thing means going to do right is to push the base pointer onto the sack Right, so whoever called me. It doesn't matter who it is. We're gonna save that base pointer Then we're gonna change The current base pointer to be where the current stack pointer is so this base pointer somewhere up here we're gonna have this point to So now the base pointer points to Fd2d0. It's gonna be right here then we're gonna Move the stack pointer down 24 bytes to allocate that space on the sack Right and so the question should be well, why are we doing that? So let's keep that in mind So now what going back to the C code what's the first thing that happens in this main function, right? So the very first thing that's gonna happen, right? Does this declaration do anything the first thing that's gonna happen We're gonna call this function Right, let's call the function. So we've just created all of that. So we want to call a function We have to look up. Okay. How do we call a function in our calling convention? Well, we push on the stack The arguments that we want to pass to this function from right to left So here so what's hex 28 in decimal? 40 right, so we're calling this function call E and we're passing the values 10 and then 40 So here is the current stack pointer, right? And we need to push values onto the stack from right to left So it's doing it's moving 40 to ESP plus 4 Which is up here and then it's gonna move 10 into on the current stack pointer Right, so we've set up We're passing these values 40 and 10 to this function call E by putting them on the stack in this order So if we go back to why is it why did it subtract 24 bytes here? Well, it's actually doing some optimization It's creating space for local variables and it's changing the stack Such that it can call this function without actually pushing and having to move the stack So we can know based on the stack pointer exactly where to push where to put the values onto the stack Why specifically does that? I don't know. It's got to be some kind of optimization thing Okay So why doesn't this say call call E? there's instruction Yeah, it's just a name that we gave some piece of memory, which is the start of a function, right? So when the program actually gets loaded, right your linker Resolves all the references so that our program says hey call 804 83 94 which is should be that address of call E So the call function does two things It's gonna start it's gonna change the instruction pointer so that it starts executing at whatever that address is But it also pushes the next address that would have been executed onto the stack Right, so normal jump instruction. Just as go start executing there, right? But a call instruction will put 804 83 BF onto the stack. So this is also part of the calling convention We have to we pushed all the arguments then we're gonna push the Return instruction of where we want to be executed when we come back Let's see what happens. So it's gonna push 804 83 BF which is this address and then it's gonna start executing this call E function Now call E just got called, right? It doesn't know who called it. It could have been main. It could have been one of a hundred functions, right? It doesn't matter But it knows that it's gonna use a base pointer So it's got to save the base pointer of whoever called it. So it's going to push Fd2d0 which is mains base pointer on the stack It's gonna set the current base pointer So remember the base pointer right now is pointing to mains base pointer It's gonna change it to point to the current stack pointer. So now it's basically saying, okay Now I am the function that's executing and I have my own base pointer And now it needs to access those parameters right The call E function just returns a plus B plus 1 So using that convention, right? Just like we saw that local variables are negative offsets of the base pointer Here parameters because of the calling convention if the base pointer is here How does it get from this base pointer to the first parameter a? Before we'll get you here Eight right because it knows that okay when I get called. I'm on the stack at this point This is my base pointer I know directly at that point is the saved base pointer of the function called me Right because I put that there then I know according to the calling convention above that is the instruction that I'm gonna The saved instruction pointer of the function called me And then above that is going to be the left most parameter and then above that the second most left parameter And so forth all the way up. So this function when it gets compiled. It knows exactly okay. I want to get parameter 2 I know I have to do I Don't do the math, but it knows exactly what offsets to do It's gonna be a constant 8 plus whatever the size of all the other arguments are on the stack so We move the stack where the base pointer so now the base pointer is also pointing down here now It's gonna actually perform the computation, right? So it's gonna say okay take evp plus C So plus C is gonna be 12. It's gonna be here Hex for the value 40. It's gonna move that into ea x but before that Right, so we think about function frames Right, we have the function frame for main up top Right, so this is mains function frame and we have colleagues function frame here Which contains all the parameters and if you have any local variables any local variables here So one of the key things here is why is it laid out like this like main callee? Why isn't it switched around? What does this represent the fact that they're on top of each other like this? Yes, the order that the functions were called in in the current execution of the function We know by just looking at these function frames that callee was called by main and that main was called by whoever's function Frame is above that right and if callee actually ended up calling main again There would be another function frame for main on here and if main called callee agent There would be another function frame for callee on there So if you if your program went with main callee Callee-callee Then we wouldn't actually you the memory wouldn't just rewrite over the first coffee We would actually allocate a separate exactly yes every invocation of a function gets its own space on the stack So what happens the stack it's full is that what would create the stack overflow or exactly? Yes Right, so you have a function that calls itself recursively Right, but the terminating conditions are bad Right, it's gonna create like let's say if you had to callee calling itself without any stop it would keep trying to allocate space on the stack and Eventually you're gonna get to memory. That's not allocated. You're gonna it'll throw an exception. I think on see it would throw a seg fault But on Java it would throw a stack overflow Or C sharp I think also does stack overflow Yeah, so that's exactly where this comes from right because we're not reusing memory because every invocation of a function Has to have its own chunk of memory that if we just Infinitely allocate functions at some point we're gonna run out of memory, right? We just can't have an infinite allocation of functions So this is one of the key things I want you to get out of this is The function frames and how function frames on the stack correspond to the execution trace of where that function is Can we print out stack trace out? Actually, it's funny that you ask I actually have a fury student working on that Right now because I think it would be super useful to have in this class Yes, you can do this, but you have to use the debugger and you have to like Print out the values of the stack and you have to like create this thing like that's actually exactly what I did to do this right as I like Created this program. I stepped through it instruction by instruction and made sure that everything was actually happening the way it was supposed to The other thing you can do is you can also do it like we did here and just draw it, right? step through each of the assembly instructions and see As long as you know exactly what every instruction does then you can simulate what it's doing on like a PowerPoint computer in this case, so let's continue this right so now we're trying to execute the values a plus b plus 1 so we're going to move ebp plus c which is B Right is the second parameter to this function hex 28, which is decimal 40 into ea x Then we're going to move ebp plus 8 which is a or hex. Sorry. It's 10 which is hex a we're going to move that into edx This I think I mentioned the load effective address is a really complicated way to just add EA x to edx and put it into ea x So it's going to add those together then it's going to add one to ea x Right, and so how does callee pass the return value to me? You have to put your return value in a specific register to return Right, I think the same thing happens here. Yes, which register? Yes, yes And where's our return value? Yeah in the ex right? We just did all this calculation We're putting this value here, and now we're done right we did return a plus b plus 1 Well, we've done a plus b plus 1 and now we need to actually return that value here So we have to make sure right? We got to make sure that we Properly put back this base pointer, right? So we're all done with executing now. We need to go back to Maine and have Maine start executing Right, so we need to make sure we put Maine's base pointer back and then we need to make sure we start executing wherever Maine told us to return to Right at that memory. So this is exactly what's going to happen in the epilogue here So now we're going to pop ebp, which can take this value on the stack Copy it into the base pointer So now the base pointer points back up to Maine's base pointer and a pop moves the stack so the stack moves up one and A return a return instruction is the opposite of a call It's also you can think of it as a pop ebp So take the value on the stack move it in the instruction pointer and move the stack pointer up So now we're going to take 804 a3bf put that in the instruction pointer, and we're going to move the stack up And now look everything's perfect, right? The stack is exactly where it was when we called call e Right, we have the return value of calling that in the eax register And our base pointer was put back successfully when we start we're going to start executing right after this instruction Make it go all the way up This one. Yeah, there's two pointers here. So there is the At that point. Okay, so before here both the base pointer The base pointer is at fd The base pointers at fd2b0 and the stack pointers at fd2b0 So this pop ebp is going to take the value that's on the stack Put it into the base pointer and then move the stack pointer up for So this is why now we have the stack pointer will point at fd2b4 and The base pointer is going to be way up there. So that's why it moves that far It's not that the stack pointer moves that far So now we have a function call, right? We call the function. It's done some work the function the calling and the important thing right is that the calling convention makes sure that After this instruction is called everything's in a consistent state, right? The stack pointers where we wanted it to be the base pointers where we wanted it to be the function did something the only register Well, that's not 100% true. But at least the value that we want is in register eax So now we can Go back and we can look at okay was main going to do after this function call if we go back here now We're going to return a for me, right? So you're going to set this to the local variable We're going to turn that local variable. So we're going to move eax into ebp minus four Right. Why ebp minus four be allocated all that space or the local variable a Exactly. So the compiler just said okay at ebp minus four in main is going to be where a is located So remove eax into ebp minus four And then we have the return instruction, right? So this actually finishes the a is equal to call e 10 comma four Right, it invokes it and then it copies that return value into eax and Then we have return eax is the next instruction Right. So then we actually have to take the value that we just had in eax Take it out of ebp minus four copy it back into eax and then now we do leave and return so now we're done right we've executed main has executed it's put its return value into eax and Now it needs to put the stack the base pointer everything to when it was called Right. So the leave is the opposite of these two instructions. So it first Sets the stack pointer sets the stack pointer equal to the current base pointer So the stack pointer is going to move from here up to here and then it's going to do a pop Evp, which is going to copy this value on the stack into the base pointer So it basically gets rid of all the local space allocation that we did here plus puts the base pointer back I think there's all three of these. Okay, so it's gonna move the the stack pointer up to the current base pointer And it's gonna pop this value into the current base pointer and Now we're gonna leave right which is exactly the same thing that call e did is we're gonna There's maybe some instruction pointer above us And so we're gonna start executing from wherever they were and the stack pointer is gonna move up Yes, so the reason why there is not any instruction and don't create any space on a stack or Yes, so it knows that it's gonna be at the same location. So we don't need to move it at all Like why I think it would still be function equivalent It may be less bytes or something to do a pop evp than a leave instruction that I don't know Yes Cool so questions on this This is exactly just this is what happens every time a function is called in your program, right that program you write This is exactly what happens. Cool. Okay So in the example we just had how were parameters Right passed to the function Yeah, it copied, but what did it copy on the stack did it copy like the address of the variable a The value right yeah copied it pushed the values onto the stack Yes, so When you invoke a function, right when you're passing So now we've looked at a lot of different semantics, right now The semantics of parameter passing and the different ways that this can happen So there's three different approaches. We're gonna look at pass by value, which is the normal thing that you're used to or should be used to in CNC plus plus passed by reference and passed by name So these just give you the different ways of what does it mean to pass parameters to a function? So pass by value is It should be kind of similar to play you think about it, right? So you are passing the actual values at function invocation time So the values are calculated and then copied to the function, right? so the function receives a copy of those values that are passed in and We just saw exactly how that's done for C right in that example that showed us how a copy of the values are placed On the stack for that function invocation So if we look at like a very simple example, so here we have a we have a main variable x. We have a function in main We have a local variable y is equal to 4. We call test with y We're gonna print out the value of y and we're gonna return y here. We have Function test test is gonna say x is equal to x plus 5 and it's gonna print out the value of x So this x is equal to x plus 5 Which x is this going to refer to that was passed into it the parameter why? Because it's more Because it's more local Is that like? Shop local, but like really local It would be closer remember like it would be stored in the function frame of test. Yes, so what so we talk about scoping rules, right? So here This parameter x is in a More local scope right than the global x right does this occur both is this true both with Static scoping and dynamic scoping In this case you'll be cheering for both right good because Dynamic would still look at the closest block if we were to draw that table which would still be the index in the parameter Yes So yeah, even in dynamic scoping right we need to look up this x We first look it up in the local scope We see that there is an x declared in a local scope right and then if it wasn't there then we would look it up in Whoever called test Right to see if there's a variable there declared Same thing with y here right this usage of y Static and dynamically is going to both be the same because it's in the same local scope Cool if we compile this with All right, so we compile this with pass by value right so this is a pass by value sample. So what should this output? So with the first line that's going to be Executed to print out the one in test. So what is this going to output? nine so Four is said to local value value. Oh All right, sorry. All right four is The local variable y gets the value four then we're passing by value right we're copying four into test Right so that the formal parameter of test this x it has the value four and then we set four x is equal to four plus five which is Yeah, it's a softball fine, right, so we print out nine first then test returns and then This prints out the value of y. So what does this print out? Why doesn't it print out nine? But we just changed x in here Yeah, so it's a copy of it right that's the important thing is is test receives a copy of all these things So when you modify that and we say x is equal to x plus five Right, we're changing this copy and we actually saw so this is exactly how that's implemented and why this works in x86 Right because this value x is actually on the stack So we want to invoke this function. We copy whatever's in main of evp minus whatever where y is We copy that value onto the stack so I'm gonna test gets it it gets that new value That's on the stack. It's not even talking about the same value So when we execute this it will output nine and four So we can see if we do a circle box diagram for this, right? We know that okay when this executes y is going to be equal to four right and then when test gets executed now we're copying that value for into The value associated with the variable x right so x is going to have the value four When this is in vote, but any changes in modifications like when we have x is equal to x plus five that's going to change x Right, but the other completely different boxes, right? They're separate and then when this returns Now when we print out why we're just printing out y as four. That's the value in second line Everybody get passed by reference or pass my bag. That was a trick Are we going to do an object example or is it a permatives? What's the difference? I mean it should be the same thing Yeah, extra like just more to show No, we will So I'm talking about the concepts. I think that muddies things a little bit So we'll talk about that we will talk about what is Java That's where it gets tricky Okay, so with pass by reference, right? This is a completely different way to think about this saying okay Instead of passing a value or copying that value in there I want the formal parameters of the function to be bound to the locations associated with the actual parameters Right, so this goes back to box circle diagrams bindings, right? We want to actually bind that name to the location that was passed in Okay, so what does this mean if we want to pass by reference? What does this mean about what kind of When we invoke a function and we're using pass by reference What does this mean about the parameters that we're passing in? Would they be pointers boxes boxes what does that mean why? You're passing in the location Right, we have to bind it to a location if it doesn't have a location that we can't buy what's another way for something that yeah Yeah, we'll see we don't actually even create a new box for X right we find Yeah, so what does it mean when something has a location associated with it L value. Yeah, so The actual parameters so they must be L values right when we invoke a function. We have to pass in L values, right? We can't pass in 10 Because 10 has no location associated with it. So if we change that what does that mean right that doesn't make sense So let's look at an example of pass by reference Same example. We have an X. We have main Y Right, so this is a C++ example. I believe so you can put you can choose how you want references to happen in C++ Other languages, maybe it's always pass by reference, right? It could be it could be always passed by values This is one of those romantic things that really depends on the language itself So I can compile this is it going to compile? Yeah Yes, when I run this now, what is it going to output? 99 99 Okay So it's gonna output nine right so this is exactly the same thing that happened the very first time we saw this right It's going to output It's gonna pass in four right X is gonna be four. It's gonna be four plus five is nine It's gonna output nine right so the only the big difference here is what happens when test returns Because we assigned to X one of the parameters that was passed by reference Exactly So it's going to be nine so if we look at it with box circle diagrams, right? So we have Y we're gonna Set copy the r value for into the location associated with Y Then when we invoke test Right X is passed by reference So it's going to be bound to the same location as Y Right now when we say X is equal to X plus five We're changing the value in the location associated with X which is here right and Then when we print out Y we print out nine. So is this useful? Why Yeah, more than one return value So why do you need why would you want more than one return value? Well, how does this get you more than one return value because you can pass multiple things by reference So if you create like let's say you want to pass out three values And you just create them before you call your function and pass them by reference you have access Right, so is it we see so do you strictly need pass by reference to do this? No, no, how could you do it otherwise? Structures, I could create a structure that gets returned the values that you want, right? You could use global variables that'd be a little dirtier though Right, so yeah, actually to be completely honest Nice or languages actually will allow you to return multiple return values Right, so that kind of actually gets around even needing to use this because Yeah, so actually it's most of them so it's all a question of can you do it? Yes, so like but a lot of it is you return a tuple, right? Which is kind of cheating It's one thing yes, but it also the language actually supports it a lot better so you can do You can do something like So the language actually helps you support this right so this is if this we're going to tuple it returns the first It says the first one in the first and the second one in the second so that way it's kind of under the hood It's all tuples, but doesn't really matter. Yeah, exactly at least from calling it. It looks nicer You can still do this doesn't see plus plus have like a pair class. I think there's also a tuple class So maybe the newer versions so they're they are slowly getting there The other reason is they provide mandates like references, right? So you can pass variables by reference and that's actually the style of doing C and C plus plus is that? Like style and I guess you consider it fashion is kind of a huge part of programming languages, right? It's like if everybody program C is used to doing it in this way Well, then you don't do it in some new different way because people aren't used to that and so they don't understand what's going on Yeah Swift oh nice cool Yeah, it's probably it's one of those things that's more of a It's more of a syntactic thing because you can just translate all of this to Tuples right, but it's nicer as a programmer to be able to do this because you can write functions that return different things I guess it's also really used in C especially because Dealing with lists so oftentimes you not only need to if you call a function that creates a list you need to know You know pointers that list and you know the size of that list right so that you can properly deallocate it and everything So that's not a big area Okay, cool. So now Okay, now we're gonna talk about pass-by name. So it's gonna be something that is going to seem crazy so it's Actually, it's important to learn about it to understand like okay. This is how crazy you can go with design And actually there are practical reasons like it's actually easier to implement pass-by name than pass-by reference or pass-by value or it can be The idea is when you invoke a function you do a textual replacement of all of the Inside the function all of the references to the actual parameters are replaced by whatever the formal parameters are switch that the formal parameters are replaced by all The textual expressions of the actual parameters So yeah, so the formal parameters in the text of the function are replaced by the text of the actual parameters everywhere in the function and Every place that they occur. So let's look at an example. So same example So what's gonna happen is when this test function is invoked with pass-by name? All of these x's here and here. They're only replaced with y's With this text here So it's gonna be y is equal to y plus five and print out the value y So let's say we have some GCC compiler that actually uses pass-by name right It's gonna execute. What's output gonna be? 99 just like references right, so Yes, so the other important thing to note is that this function These y's right actually have access to this scope, right? So they reference that y this is not this y here This doesn't shadow anything this basically you can think of it as if you took this function test the lines in here and replace them here with test and By changing every x to be y in here. So yeah Just like Ah Not quite. You mean the x of the parameter to test Actually, it's even crazier, so I think It's actually how it's done and that's I was a lot easier to do it that way because you could just Kind of replace that function in line. You could actually easily in line every function call I guess unless it was a recursive one, but yeah, so you said it makes a copy of it Kind of yes, so it doesn't that's what I think about it Is it like every invocation of this function is kind of different because it depends on what you actually invoke that function With the structure is still gonna be the same You'll always have something equals something plus five and you'll print out something But whatever that something is is replaced by whatever the text here is of this invocation I think there are more hands. Okay, so let's look at a more complicated example So here we have a global variable. I love an array a We have a function increment Which increments I and then increments x we have a function main. We set I to be one Right. So what does I refer to? The global I Right and this x refers to this parameter x So we said I is equal to one. We say a one is equal to one We said a two equals two and then we increment a I and then we output I and a one and a two What is it going to output? Passed by me So let's think about what what this function increment looks like Yes, so it passes an AI so AI is not evaluated at function in vocation time, right? AI happens wherever x appears and every place x for peers a bracket I occurs So what this essentially this copy of this function is going to do it's going to do I plus plus And then it's going to AI plus plus and you see that just by switching the order of these two It's going to be something different So if we we can compile this we would run it and it would output What so what's I going to be? to definitely be to What's a one going to be one one and what's a two going to be three three? Yeah Well, even when you inline functions, right? I mean with C or C plus plus they'll do it so this doesn't happen so it's kind of like It is it's like textual inlining like pre-process or inlining in some sense. Yeah Why doesn't it pass AI while I as one is a one? Because this is it so it's not so the invocation of this function It doesn't evaluate that expression and then copy the value in there It textually replaces all instances of this X with whatever you put here So it's not actually evaluated when you invoke the function Yes, so it means that this I is evaluated whatever AI is is evaluated at this Execution time here for this X. Yeah Yeah, it's really weird and it's really cool and actually The thing is you actually easily Enulate this using pass by value and pass by reference, which is also cool. All right, so we will stop here We'll go over this a little bit more on Wednesday