Updates: Tyler on PowerHacking CSS to cutestrap your app in this latest episode!

Topic 4 - Functions and Stack Frames

Outline:

  • functions for organization, reuse, isolation
  • scope, stack memory, simple non-optimizing stack machine
    • “gravity stack” of coins, LIFO basics
    • non-optimizing compiler just does what you say
    • ignoring padding / alignment
  • winding up the stack
    • LTR/RTL, caller/callee cleanup
    • pascal: LTR params, callee cleanup
    • variadic function problems
    • cdecl: RTL params + caller cleanup
    • stdcall / win32: pascal with RTL
    • optimizations / fastcall / unrolling
  • building stack frames, variable sizes, local memory
    • some extra items - return PC, registers
  • fibonacci example, same variable names / different scopes
  • only one return value; preview of structs / pointers
  • stack smashing, growing heaps

Transcript:

hello everybody how are you
tonight we have jess who you can hear
her keyboard hi jess
hi sorry guys oh no you're good i just
caught her with a quick we're going to
start now so
all right um this is c as an additional
language
topic four functions uh for those of you
who are here
last week this is completely different
show than last week actually
not at all that was just topic three um
we were doing while loops we were doing
iteration we were practicing we were
covering the real types we're supposed
to use because i never write int and
care and i use those old-fashioned types
is that right jess
never ever totally ever never totally
never ever
ever no one look at the vod um
[Laughter]
and hello everybody in chat we have oke
gone we have
the enceladosaurus we have fossils
all right yeah it's a party now by the
way i would like all of you to know who
were watching earlier
those dice that's a real camera i rolled
that 20 that double
20 right in front of you
i'm just gonna take a moment and think
about that because that that just blew
my mind
i want to just let's look at it i'm
lucky i feel like
we never just look at that double 20.
i i can i have that look in real life it
i mean
like you you saw the roll i threw it i
just
all right i i feel good about tonight
jesse is
very lucky i'm sorry the enceladosaurus
is very lucky
clearly that's not coming from me okay
so um
great well we're gonna be following the
same sort of format as last time uh i
think
that works better i think i think the
enceladusaurus was happy with it i think
i'm saying her name right
you are awesome so
yeah loaf phone we're going to go buy
lottery tickets that is just
completely agree uh i'm going to try to
be succinct because
rather surprisingly uh one of my
favorite streamers
in addition to the enceladusaurus uh
happens to be doing a live music
thing tonight that's 88-bit music so uh
i'm if if i'm rushing too much and
celadosaurus just stop me be like no no
no stop
rushing to try to go listen to video
game music live on piano
oh wait so you have to share the link
obviously i am sharing
music i'm not sharing we're rating yeah
all right there we go we're gonna do
that later so um
but uh anyway no uh so i don't want to
rush too much because you know
general format we're gonna we're gonna
stick with um kind of doing
the more learning stuff up front and the
more uh just
general stuff in the back and probably
not as long as the last
so anyway um our main topic for today is
functions so uh we just got a new
version
uh with all of its brand new bugs of the
oh this is our overall topic lesson plan
this is our new version of the editor
and it now supports group selection so
these
these code changes were just checked in
so theoretically
what did i just highlight in cell
description uh
you've highlighted main parentheses the
stuff
inside of the parentheses that's yeah
you hear that everybody
actually she could be looking at the
stream i guess i guess that's not a good
uh i saw it before the stream okay i
knew it before it was cool
okay all right awesome um so she gets
kind of a low lag version of selection
so
the tool's getting a little bit better
um great
uh so here's where we are we we're we're
done with all that stuff there's not
many topics left in c you know c is a
pretty
simple language that's part of why it's
so portable that's part of why everybody
it's been around and stood the test of
time there's not much in the language
so we just have functions then we're
going to be using functions with
standard io
then we're going to do a little more
with dynamic memory today we're going to
be using static memory
and then we might touch a little bit on
missing parts and that's pretty much it
at that point you're a c programmer
you know
yeah it's just you know practice after
that really
oh good lord so
we're gonna be here let's uh let's get
to this stuff so
let me i've got the glove on we're ready
to draw on the board
and i can look cool with my partial
partial fingers
i am so ready for this all right let's
uh find
the white board okay so here we already
have
this up i'm going to knock these
beautiful 220s aside
and we're going to get to drawing okay
but we're not going to use that green
because i've already used green
okay but green's my favorite color okay
then i'm gonna use a different green
then different green
okay you like you like green huh all
right cool
the color of plants it is and apparently
we have more
optic sensitivity to green than any
other color
the sun's uh uh
spectrum it's light spectrum it's em
spectrum peaks in green
interesting it's a little factoid there
for chat
factoids i'm full of them
more green
[Laughter]
um so all right functions what are we
gonna do with functions functions
are about um
isolated call spaces so we have actually
our first function is already
up on the screen and
the enceladus horus is going to memorize
it
in her bones
copy and paste yeah
we're going to go beyond muscle memory
on this one and that was a it was a bad
g so i'm gonna
i'm gonna undo that g we're going beyond
muscle memory here and we're gonna
this needs to be bone memory okay so
um and like we're used to seeing this is
sort of the uh this is the name
of whatever our function is this is the
return type
so this function has to return an
integer um
and this these two are kind of some
magic from the operating system
that i have not described but tonight
we're going to find out what they are
i don't know if we're entirely ready for
that but we're not going to be dealing
with this system function this is kind
of like required this is always your
starting point
so the the c runtime the the startup
script specifically it's called crt
0. you don't need to know that um we'll
always
look for this symbol and it will start
there
and so that's kind of like where the
action begins for your program
so we are going to make our own
functions now the
this thing is not going to go find it
for us so we're going to have to call
our own functions
um and celadosaurus is already familiar
with the general style
of functions but we're going to be
talking a bit more about like
what's happening at a lower level
because python kind of
does all this magic for you and
[Laughter]
probably doesn't give you a very good
description of what the machine is
really doing but we're gonna we're gonna
be doing a little bit more
now we're doing c so we're getting
closer to the machine so i'll
i'll give you a nice little computer
classic pc
here with a light and a little turbo
button
is that what that is yeah that's okay
all right let's get rid of that
art art is not my strong suit okay so um
what what happens with a function
function's all about
kind of like an isolated place so
we have in here we just had our main
function
and in it we were declaring stuff like
integers
uh characters what were some new types
that we learned jessie
uh you and and various
bit types underscore tea yeah um
we also had long briefly
double i think at some point but i don't
even know that one's still hazy for
me long is you know usually
the same size as in these days but could
be longer
and how do we find out how big they were
this just quick recap from last time
size of you got it okay so which is
an operator
yes it is i remember
so that is an operator it's not a
function
so it is in the base language and hello
sunny how are you
uh sunny is commenting that there's also
a long long
type and all sorts of other stuff but at
this point by the time we kind of got
here
we're gonna start using these new
portable types as opposed to these kind
of like older school types
all right so what do these types do
they spell out how much memory right
so when i was doing like if this is like
you know let's imagine we had a a world
where there was a 16-bit
long um sorry a 16-bit in this was like
kind of back in the day
and that nowadays is referred to as a
short
but um it's small yeah so
like if this was eight bits wide and
from here to here
and this is eight bits wide from here to
here
so we got 16 from here to here this is
kind of that that short type that still
exists but you know nowadays hint is
really almost always
32 bits so we have to go in here and
here and there's no
standard 24-bit type so
this this this doesn't happen as a
standalone but
this does happen as sort of like inked
and long until
long sometimes becomes 64 bits and
sometimes it's 32 and that's why
we stopped doing that so we start using
these these affordable types
okay right this is important um
because we have we're spelling out
exactly how much memory we're using for
every one of these variables that's a
little different from python because
python i could start off saying x is
five and then
a few lines later i could be like well x
is now
you know nc
[Laughter]
and that's kind of fine in python right
you know i mean it's not it's not
exactly
preferred python but you know you could
do that um
dynamic languages tend to allow things
like this like you know javascript will
definitely allow it unless you're using
like a typescript variant but
um you know so this is kind of like fine
you can sort of do this type
switching depending on context but c
types are very literal they're
they they mean like how much memory and
when we start talking about functions
all of these
types whenever we declare a variable
it's owned by a function
or it's owned in the global space so
that's really our only two options we
can either
like if we say like int x then
either this thing is outside of main
you know i have my declaration from
maine down here and i'm sort of doing
whatever i thought nothing goes outside
of
uh we didn't yeah that's that's style
[Laughter]
so if outside of outside of any function
is the global space and we we try
not to put things in the global space
anymore we learned a long time ago that
that's kind of a naughty practice
back when when machines were a lot more
limited on memory than
global sp we tended to use global space
a lot more than we would use sort of
function space
now nowadays we tend to prefer not to do
this because it leads to a lot of bugs
you know because
you might forget like which functions
edit x
i don't know i mean maybe main is going
to take a reference to x maybe uh
you know funk a is going to take a a
reference to x maybe funk b
is going to mutate x maybe funk c is
going to define its own version
its own variable called x which is not
the same as this one
so this kind of becomes like chaos very
quickly right
i can see how that would be messy and
that it would be difficult to kind of
i mean i'm used to the mess like
literally i started with python so when
you were describing oh man this is
messy that's that's the mess i live in
my friend
but it makes sense that there could be a
better way i just have to comment that i
think it's amazing nightshade dude
recognized what can you opened
that wasn't pbr it wasn't so i will have
you all know thank you very much that
was not pbr
okay classier than that it is white claw
so there you go
so um that's that that's good hydrate
um yes so uh okay so it depends kind of
what
how do we refer to these different areas
where the the variable could exist
they're called scopes okay so i don't
know how much scoping
did in python uh
so so i think this let's just say none
because to me
scoping sounds more like words that i've
heard used in a consulting context
really than i've heard apply to program
i mean when you say like the scope of a
function
to me there is an intuitive
understanding of what that means but i'm
not sure if my intuitive understanding
is really the technical
definition that you're looking for
that's fine your instinct is
probably right um like so if i have like
a main
imagine this is sort of like boxes okay
so if i have a main
scope and in here i define intex
and then i have like another function
which i'm going to call
func a and in there
i define int x this is this is valid
okay because this x stays inside the
function
but they are different x's this x stays
inside the main box
these two x's are not in the same place
in memory
so and they also are not the same that's
correct
because they're different memory
locations this is c so a variable is
literally a location of memory okay
so i mean the whole type thing is really
just about telling us
how much memory is related to one
variable but ultimately
it's just specifying like i want you to
like this is really going to be living
at some address and memory so
memory we can view is just this massive
stack of stuff
and it's all these locations
and each one is eight bits
and you know if i'm doing an int then
i'm taking four of these so
this might be x and if i take
a care i'm taking one of these so if i
do like you know if this is
int x and this is like care y
then that's going to be this box and
then
if i don't care about byte alignment
which at the moment i don't
then which we'll get to that later then
this might be like
in y okay now
because of this scope thing i can reuse
the same variable name
because this int x
applies to like funk a whereas this
index applies to main
so despite the fact that they're both
called x in sort of the program text
they're not the same variable because
they actually point to different
locations
they're different parts of memory that
makes perfect sense absolutely so that's
really
what scope is about scope is about like
kind of drawing a line saying okay this
stuff
below here this is the main scope
and this stuff up here is the func a
scope
and this next chunk that we're gonna do
that's the funk b
scope and so on right
so it kind of reminds me a little bit of
in object oriented programming when
you're using classes how you can have
kind of
you know instance variables and you can
have class variables
and so i'm probably not using the right
technical terminology but like
later but they do have this scope notion
kind of well what i mean there is that
like one
just because like if you have something
that is encapsulated
in a particular function or instance
instantiation of a class
like that applies to that relative
instance only it is not a universal
and if you have something that is
outside of that
then it could perhaps be a universal but
you have to be very careful about like
what things are relatives and what
things are universal and i understand
that's like a
like i'm using terms here from
philosophy
and math and also my understanding of
programming and i'm not formally
like actually programming educated so i
think it's probably your field that's
biasing you there because universal
is probably unique okay something that
you think more about but
programmers are much more uh down to
earth and they're just global is already
pretty big for
for a programmer so um but
you should just drop that term universal
basically your instinct is right
i'm agreeing with coffee uh and fafia
i'm sorry i
uh shouldn't shouldn't have answered
so i should have i should have no no
we're all excited and we're all
enthusiastic
yeah little it's a little fired up so
my bad um okay so how does the compiler
determine how much of this
meant so if this is all of ram
then how does the compiler determine how
much of this
is uh related to mit like main versus
funk a versus funk b
i feel like this is this is oh shoot i
should have written down the term that
you said earlier that you were like
we're not getting to this yet
it's like bit order or something
what's that um there is in terms of
there's a bit order thing
uh i'm just trying to turn you down a
little bit i think i've got the
volume not very well balanced uh can you
sleep for once
hi usually i'm very quiet so i was
trying to maybe like
project a little bit more because
usually i get told that i'm too quiet
for once i'm not all right um
yeah and chat let us know how uh that
sounds sounds ball parkish now is what
moshi moshe's saying
um all right maybe maybe i'll go down a
little bit more uh
anyway uh keep keep it giving us
feedback chat in case uh it's not
not right okay so um you are right about
this endian thing
that really applies to like left to
right or right to left within a given
type
so if i'm like talking about an int
and i'm on a big endian um platform we
did talk about endy and niss a little
bit in the first session which was a
mistake on my part
[Laughter]
um then the most
big endian kind of works the way our
normal numbers work so if i have the
number of 1000
which which number which digit is the
most important
the one yeah it's the most significant
digit
is on the left right
so the most significant digit
is left okay so that's kind of big
endian
um little endian is the reverse
so the most significant digit i would
write this as zero
zero zero one if i was going to write it
as a little endian number
okay but the number value
is the same like either way it doesn't
matter if you're reading if you're
somebody who reads left to right or if
you're somebody
reads right to left they're both a
thousand
once you agree on which way you're gonna
read for this given architecture
so um yeah it's convention yeah it's
really conventional we
generally computers use the the little
endian architecture is kind of worn out
over the big endian architectures
um but network byte order which is kind
of how the internet works
uses big endian so that's going to get
messy later
so um and yes i really like nathaniel
bumpo's example um that
this would be um big endian date writing
would be like
20 20
20 but let's let's use today's date
what's what's today's date
that's the one he was skipping five
four versus little endian would be
four five 20 20
and american
[Laughter]
broken indian would be inside out indian
it should be 5 4 20 20
because reasons okay and
too bad nathaniel um okay so
broken indian nice so um
yeah we can i'm gonna borrow from
silicon valley and call this inside out
like inside out compression okay i don't
know if anybody watches silicon valley
here but
um there are too many dudes in it yeah
it's it's a documentary
about silicon valley
it's it's not a comedy so
and for you know exactly what you just
said it's true you know i
used to refer to it as man jose because
it's
san jose is really fantastic okay i just
you know what there's there's a certain
thing for me where i promise i won't get
tangent but like if i have to deal with
it every day in my job i don't want to
come home and watch a show about it like
my shows are for escapism
you know no i have that i'm just like
post-apocalyptic the world is ending but
also sometimes escapism is like i don't
have to listen to a bunch of dudes who
think they're way cooler than they are
sorry but like i get paid to do that i
don't get paid to watch that show
so let's let's let's throw that on the
topics list yeah we'll put that on that
second valley dudes okay um
oh boy all right so uh i'm gonna we're
gonna come back to that one so
all right back to my question so ram is
all about
um breaking up ram
programming is all about breaking up ram
kind of into chunks
so how do i know what's going to like
where the line is for
this stuff is main and this stuff is
funk a and
this stuff is funk b i'm guessing the
answer is scope
and all of this stuff is really funk c
and scope is actually kind of like where
these lines are right
so scope is like this is this is funk c
space
and this is funk b space and so on but
how does it know where to break memory
because memory is
like it's got you know memory's not
divvied up on the chip
right it's just i mean is it just how
much memory you use
in that particular operation yeah
because how do we declare how much we
use
well we tell it we declare our variables
so that's exactly we we we specify okay
i want like
an int you know to be here and the pro
the compiler doesn't really care what
you call it as long as it's something
valid
and then we want another int to be here
and how many bits is an int normally
16. uh it was in the example that i
showed before that's really naughty
i mean modern modern 32 modern 32 okay
so
it says okay fine 32 bits is going to
this int and
32 bits is going to that end so
if these if each one of these blocks is
eight
how many blocks do i need oh lord if
each of those is it four
five six seven eight eight what's that
eight and five thirteen thirteen
thirteen times eight um i'm trying to
count here are you just talking main are
you talking the whole ram
oh oh yeah sorry um for main 32
um if i've got two ins
then each of these 32s by the way this
we're talking we're mixing
bits and bytes so here we're talking
about bits and
we could be talking about modern bytes
which are really octets
and octets are really all about eight
right eight bits in one octet so i can
think of a
int as four octets right
just for octets yes right which is the
same as 32 bits
so if i've got it now if i've taken my
memory and i've broken into octets which
is
typically how memory is organized these
days then
i need four of these for one integer
right right okay so if i define two
integers how many do i need
64. uh double it's 64
bits so how many bytes
eight exactly
so okay yeah so math
not making a mess let's let's make a
bigger one so
um all right so if one of these
is eight then this is an int
worth of memory and this is
another int worth of memory
all right so if i was calling a function
which had func a and it has
two ins you know i have int x and int y
the the compiler's going to read this
and go all right
one of these is 32 bits which is
four bytes so you need one two three
four and the second one is going to be
the same thing one
two three four i'm going to say that
that's the end of my function so funk a
you get this much memory so this whole
thing about declaring variables
is about determining how much ram we're
going to give to a given function
make sense yes i would say that like
i can see serious serious downsides to
this
just in terms of
i guess when i think about trying to be
this conscientious
about my memory usage i understandably i
don't have to do that
okay but i'm thinking like let's just
say that i could you know
you know but thinking about how much
memory i'm using in
a lot of cases when i am
for example using machine learning and
things like that a lot of times there is
kind of a
an ambiguity or an unknown unknown
element
in terms of the either the parameter
space that you're exploring
or what kind of you you might expect as
a as a fit to that parameter space
and i can't imagine knowing
it's like knowing the answer to a test
before i take it
we have to know the answer so in the
case of
c which is literally like compiling
something to run directly on the machine
we have to know exactly how much memory
to allocate to each function
ew that's that's kind of how the
language was designed
and i understand functionally speaking
i understand why that's a necessity and
it does make sense
but when you get into more of the
exploratory element
of a lot of modeling and whatnot i find
that that could be overly restrictive
it's very restrictive it's
and yes it takes a lot longer because
you actually have to spell out
everything you're going to use and maybe
you don't know
but we're going to get to that shortly
okay so the important thing is to kind
of build this concept in your head that
each of these functions
kind of has like a fixed part of memory
that's going to be associated with it
this by the way is called the stack
so okay um stack is probably
not a term you might have heard in in
python land oh i haven't heard it
i think in this particular i think we've
all heard kind of like full stack
development and stack used to describe
that kind of like application
yeah i think this is not an application
this is like kind of stack that's like
yeah like for example
linux you know to use like an old one
like linux
uh apache
my sequel actually my sequel's usually
kind of running at the same side
oh sad face
you know or do you want like php up here
yeah so
somebody who's full stack was somebody
who did all of this right and then
well and then also the the client right
so this is usually like
html and javascript and
css that stuff css or whatever and so
somebody who is full stacker the people
who can make it look pretty
yeah yeah and i'm not one of those
people in that sense like yes we are
stacking stuff
up but um no in this case
the the computer version of a stack
is actually a lot more like a stack of
coins than it is like this because
you know apache and my sequel are kind
of running at the same level there so
they they don't
properly stack on top of each other
right yeah
so but if i have a stack of coins like
you know i have this coin and then this
coin and then this coin
like i can't pull this coin out very
easily right
yeah right i mean i'm gonna have to sort
of like take this one off and then get
this one and then put this one back on
and you know if and and that that's kind
of important because
that if i if i have like a lot of these
like the difficulty of this problem kind
of scales with how many are there right
right i mean that makes sense yeah it's
like one of those logic puzzles
you know restack these boxes or
something
and yeah okay yes sorry that was me
hearkening back to
to like little video games i played as
kid but yes that makes sense yes and
in this sense we're bound by gravity
in the real world mostly
so um so we tend to think of stacks as
growing up because
you know gravity's sort of pulling this
stuff down right
okay well in computers we do it exactly
the opposite the stack grows down
oh boy okay so so our stack is in space
yes this time um so
this is one of those like the stack
typically grows from
high memory addresses down to low memory
addresses
so you fill in the big things first and
it's kind of like that idea of like
you have 50 rocks like 20
of which are big and then 30 of which
are small you want to fill a particular
jar you don't put the small ones in
first you put the big ones in first and
then you stick the small ones where they
fit
well except that the the catch is kind
of like what they're bringing up on
on um that i was sort of like touching
on briefly in the last example what
they're bringing up in chat
like with with the gravity stack i i
can't pull out
something here without everything
crashing without everything
falling down right you know and so it's
sort of the same way with like
the computer like if i if i if i try to
like pull out this piece of memory here
like it's not gonna work like it's kind
of not the mental model
um now meatball is bringing up a uh
meatball cirrus is bringing up kind of a
good
point which is that the stack growth
direction is actually architecture
dependent i can tell you that
the stacks we're going to be dealing
with today they're all going to be
growing down so
kind of this is pretty typical on intel
architectures
when we're talking about stack here like
can we root this in
some some physical reality like what
no no no not coins but like literally
when we're talking about the computer
like i understood
the concept of like allocating memory
space but when we're talking about these
stacks growing in different ways like
what are we talking about when it comes
down to the hardware we're
we're talking about ram so
how much ram i have is kind of what
this is one of the limiting factors of
programming right so if i have
i mean nowadays how much like memory
does your computer have
ram wise 32 gigs okay so this is
massive
[Laughter]
this is my divorce present to myself so
yes it is
beautiful and it's a beast beautiful
it's wonderful
it's like so much memory but you know
like back in the day
like you know c was being created like
these things were more like
so that's 32 gigabytes
and giga yes yes
like billion yes it does
it's it's tend to the oh unfortunately
it's not
tens because it's it's really uh you
know it's it's we're using powers of two
so
um oh so two to the yeah yeah two to the
something but it's going to end up being
around like 32 like
well 33x billion you know kind of
we'll calculate it in a minute but um so
this is this is a really that's a lot of
and that's in bytes right yeah we've
been counting these things so far in our
examples so obviously it is a
significantly
much much larger amount than we have
been discussing previously and
miss tran is having fun talking about uh
this is a quote from bill gates
yeah back back in the day 640 k's more
memory than anyone will ever need and
that was
back when 320k was kind of normal but
back when c was being created like 16k
was a lot
so you know this
like you used to be able to like kind of
count how much memory you had
like directly so um you could
i mean like the nintendo that i'm gonna
be programming later on in
one of my shows like that's got 2k but
you actually lose a bunch of it so it's
really like one and a half k
that's that's an nes like which oh and
you so you're doing nes
yeah so j just to give you a sense of
like
in the by the way that'll be partially
in c and uh i think well
uh make sure you let me know when you do
that because that sounds exactly like my
kind of hacking
the funny thing is in if you look at the
course program
it's actually later on so okay
so um we are going to be doing some of
that a little bit later but uh
if if you're interested uh otherwise i
might just do it on the regular show
but um this uh this kind of size is
really different from dealing with like
that kind of size like 32 gigs so we're
going to be when you're thinking about
memory
let's think in this space you know which
is kind of like where the language
designed and
then they sort of added on stuff to be
able to deal with like larger sizes
and so yes and as strophian pointed out
a teraflop was a
was a myth in those days so um
did he talk about flops with you um
we didn't talk about it in c sharp
okay so that's um floating point
operations per second
um so it's basically like how much are
10 to the 12 floating floating point
operations per second
yep so that that's a lot of math
that's the kind of math you need to be
doing neural networks okay
so um great let's get back to functions
so
each of these functions has its own
space so i've got my main space and
i've got my funk a space and
when i defined how i specify
these things i gave them lines that
looked like int
main and then some stuff here like in
argc and you know care art
okay your arguments right i'm spelling
out
to the compiler like this is exactly how
much space you're gonna take
yes especially when i take this stuff
plus
like whatever's going to be in here like
if i do int x
and y and you know all this other stuff
um that's spelling out on the memory
like okay
this much is gonna be for me
this is called a frame frame
okay that is the first i mean in a non
yeah
cinematography way that is the first
time i've heard that okay
like precisely called a stack frame but
um we're going to be kind of building
stack frames today
and that's this is kind of important in
terms of ownership and that's the reason
i'm
being pedantic about it because that
if i have like an int x that's in the
func a
stack frame that does not mean that main
gets to access it
and that's really important so these are
like
these are our contiguous
but non-interactive chunks
yes yes we can get them to interact it's
naughty um generally we don't do that uh
we're gonna use some different
techniques
we're gonna get to something this is
this is we're working on the stack which
is
kind of like the normal space for that
that's where you've been declaring stuff
when you do like intex and y
all that stuff um okay later on we're
gonna be talking about something called
the heap
um okay and the heap typically grows the
opposite of whichever way the stack
grows
so um if if this but when we talk about
direction
of a stack i still like i get these yeah
like direction what does that mean when
we're talking we're gonna get to that
reality there's a reason that i'm
not directly answering your question the
important thing
is that i trust you go for it they grow
they grow
into each other on typical architectures
so
if the stack if if you're on an
architecture where the stack is growing
up which is not very common these days
then the heap would be growing down
and if you're on an architecture like
what we're going to be using shortly
where the stack is growing which way
down you got it if the stack was growing
down
like say on your typical intel
architecture then the heap would be
growing
up you got it so okay what do you think
happens when these two meet
um i'm sorry i literally have no idea
you get to keep both pieces
okay so that's that's a crash out of
memory
basically okay all right um you you
don't ever
really want this line to hit okay
so that's kind of an obscure that
that'll happen
that's not very likely to happen on your
32 gig of
ram monster that you have but
you know back on like an nes like that's
downright likely that you're gonna smash
into each other so you have to be very
careful about smashing the stack
we're gonna get into that a little bit
later it's not it's not gonna be a big
problem
for us today but just be aware that it's
important
and strophium don't go stealing where
i'm going with that but
we're gonna get to that a little bit um
okay
so great we know how many variables
we have right yes and
if i add all them up so
let's uh
let's sum them all up is that is that
the right sigma i haven't drawn a sigma
in years that is some yep you're good
okay okay all right so i got you if we
sum up
the size of
the size of all the variables
then that's going to be plus a few
things
which i'm not going to talk about right
now then that's going to be kind of like
the size of the stack frame
right okay i mean does don't when
certain operations
take is that the is that included in the
plus few things
uh there's very little in this plus few
things it's actually really just
maintenance
stuff okay
um so what are you worried about not
fitting in there
so it's c keep in mind this is not
python with c you declare
exactly what you're doing with memory
right and no ifs ands or buts about it
and if you don't declare it you'll just
interpret it
so let's say i define a function in c in
happy
land yes like the output is going to be
um i don't know the output is going to
be up there
um well here let's do a function that
that adds two numbers
a small integer nobody here so this is
my point right it's like if i pick
a uh if i define a function that takes
in
say two two integers right so int
int what do you want to call it
uh exponential x how about
x right and it it it takes the first int
and it raises it to the power of the
second end and it returns
do you mind if we name it uh yeah um
bottom and top
okay and i'm just gonna abbreviate
bot top okay right and what does it
return so
it returns the it returns bot raised to
top
which is what type i'm like i'm trying
to think of an example where something
where the result the operation done
no wait wait wait wait it doesn't return
this was the example that i thought of
and
was the operations done in the
body of the function for example i raise
something and then take the log of it or
or whatever so like i kind of i use more
memory in the body of the function to
do something and then i shrink it so
just by defining you know
output is small inputs are decently
small
but what happens in the body of the
function takes a lot more memory how do
you handle that
it was basically my question and i was
trying to consider like an example but
probably
so is it can i call it x and log
there you go yeah okay so we have and
it's i'm gonna keep your bottom and top
okay okay and what type is it gonna
return
so we're expecting um an int
as well okay you're you're gonna return
an end okay so that's your function
specification okay yes and i would
imagine that that is kind of what tells
c
how much alec memory to allocate for
that particular
ah no no that's just how much memory to
allocate for calling it
okay because in the function
you said you're gonna need a little
working space right right
so let's call that a
ah excuse me okay
so i have an int a which is in that
function right
okay so if that's all my variables
how much memory am i using
assuming that they are
yeah we're just from now on i'm only
going to talk about 32 bit ins
i've already told you that there's other
ones that's why we use the nor the new
types but from now on for us let's just
always say
into 32 bits we're using 96 bits
well let's let's not let's use bytes 12
bytes
okay because bottom is four top is four
the return type is four that's twelve
so twelve oh and a and then a i assumed
return a so that was my fault so yes
okay so this stack frame needs 16 bytes
right i see so that was my mistake when
i was thinking about
the allocation of memory
the distinction between how much memory
it needs to call it versus how much
memory i need to
execute the function that i'm i'm good
work
my brain has been been corrected now if
i have another
if i'm if i've got main down here i'm
not going to fully specify main but
if i've got main and i have int a
what am i this is not the same a
right no yeah it's different because it
has a different uh
space because they're in different
frames scope yes
okay so i've got my in the example
x and log
and main main has its own a
and x bin log has bottom
top a return type
and a n a right
yes those are four components and then
plus the little bit plus stuff and i
keep not telling you what stuff is
it's okay okay but pretty much that's
how it ends up getting laid out in
memory now we're not going to talk about
optimizing compilers we're not going to
talk about byte alignments we're i'm
going to stay with a relatively simple
model of a computer
as good as i can
now nathaniel is referring to something
that happens because of optimizing
compilers and what's called the fast
call convention
and a few other things that oh god so
there were like 10 things in there i
didn't work
don't you worry because we're not going
to worry about that what i'm going to
say to nathaniel is
we're going to start with the classic
stack register model of a computer so
this is it the modern computer does a
bunch of things to try to make this
faster
but i can tell you that conceptually
that's not that important like it's more
important that you understand like when
you're in a frame
you're in a frame okay
um actually to nathaniel's point it it's
probably the a modern compiler is not
even going to create your function at
all it's going to unroll it
so it's it's actually going to use
nothing on the stack but
we'll get to that later okay
so does this all make sense
tentatively yes tentatively yes we're
gonna be coding
so um i mean there there is this like
small like 12 year old well i was much
older actually i don't remember when
minecraft became a thing
but there is this small desire to answer
equipolent
excellent name by the way um
where i have wanted to understand things
for so long kind of from
that hardware level all the way up but i
don't think that that is in the scope of
what we're talking about now so i would
say
hold holds please oh yeah we're gonna be
later on
um in a future lab session we'll
actually look at memory directly
so um i can tell you that this is going
to help you conceptually
with that but the important thing is to
realize that like
you have to kind of declare this is c
it's not python you can't be willy nilly
about your
variables you got to declare everything
you're going to use and you've got to be
very explicit about like what you're
what you're doing um now i just have to
know what i'm doing that's the problem
that's my deep like at a fund a
fundamental level
my issue with c is that it it assumes i
know what i'm doing
whereas python doesn't make me know what
i know what i'm doing before i do it
which is really nice
okay i mean this i have to know what i'm
doing before i do it
so now that we know what a stack frame
is roughly
that's the basis of us building what's
called a function okay now
back in the era that c was created there
was a debate between what's a function
and what's a procedure
and a procedure was just a set of steps
to do something
a function was mathematical it was like
f of x
you know so what does f x do it returns
a value
oh now we're in my happy place it has to
return a value
right so i'm not allowed to and yeah
beer open
so okay no no i'm good i'm not allowed
to not return a value okay i
have to return a value if i'm yes having
a function
okay and a procedure was all about just
do this stuff
and maybe there's side effects maybe
there isn't but it does not return
anything
so we wouldn't we didn't use the term
function now c
got rid of that notion right so it said
okay all there's no such thing as a
procedure anymore
so everything is a function it's just
that sometimes functions don't return
anything at all
and if we return nothing at all that's
the void type
strophium so much of yesterday makes
[Laughter]
sorry what you talked about yesterday
but void is over so we were working in c
sharp okay and there was a command that
i was working with which
was a void something and i was like wow
this is a really
morbid way to say death because we were
working with
functions this is great and i i didn't
realize that that's
at the bottom of the whole thing yeah
all right
well okay so sorry so there was a
connection made for me
and now some things make more sense this
is kind of where this gets introduced
the language now
void actually takes on a different
meaning later on with specifications but
we'll get to that later like where it
starts is this
distinction between a function and a
procedure and c
sidestep the problem by saying
everything's a function it just it might
return
void okay so if we don't know what to
return in our function
like for example if we're just going to
print something out like say put care
then we could just say and put what was
put care going to take
for a parameter so
it can take a character yeah or it can
take um
a an int no it just takes a character
well it interprets the intensity
if you take if you give it an it's going
to coerce it to be a character
which is casting yeah that's cast yeah
see collision and casting are slightly
different but i'm not going to get it's
pedantic something we talked about two
kinds of casting so i understand that
clearly if you call it casting or
coercion i'm i'm fine either way
we'll get into the differences later um
that might cause
strophium to choke but
[Laughter]
sorry okay so oh no don't die
okay so in the case that's the finished
pong in the case of like
put care that this is really all about
side effects
right because what does putcare do it
outputs something but it doesn't
actually return anything right it does
it just does some stuff
right so we do stuff
in here we don't really compute anything
we're not doing like an exponential in a
log where we want the value back
right right because in that particular
case what it's doing
is that it's printing it's not returning
it's printing
it's printing to like an output right
yeah which it doesn't return
it just exactly okay um so we can't say
like
x equals put care because that doesn't
make
that sound yeah no i i don't i i'd have
to check the actual type of put care put
care is a well-defined function so it
actually
it might it might return like how many
characters it actually output
like i i'd have to check but that would
be silly in the case of put care i'm
pretty sure it returns void i'd have to
let me let me let me look just i don't
want to tell you the wrong thing
yeah yeah yeah you're fine okay put care
actually does return an int so this is
this is well you know
which is you know that and and put care
returns and then because it says
like whether or not there was an error
so it's
it's using this oh
come on draw pad oh no have we lost
no no no we can't lose it now oh no
we okay good we're back okay we're good
um so putcare actually returns an ant
and it's using this as sort of like an
error message
but that's not really the same as like
you know
doing a like put care you know like
it i mean the real reason you're calling
put care is not to find out whether or
not it got an error right
right exactly you're sort of hoping for
the side effect in this case everything
shows up on output
okay um great well
let's go write a few functions how's
that sound oh no okay
yes yes yay okay sorry yes
one thing that i do want to specify
before we move on the order that these
parameters go so
let's do a simple function so give me a
function that
i'm just going to call it add two add
two
numbers add two guessing it returns an
int so yeah that that's a great guess
let's let's make it return and then
and what's it what does it need to take
in um
i mean oh you're typing sorry i was
looking at the whiteboard
um so i tried
no no that that's totally fine okay um
first of all this is not in maine
everything is a main no no no but i
thought the whole thing was
main is its own function but but but
everything we've done so far has been in
maine this is this is new yeah we're
okay
we're moving out i thought everything i
had to do was in maine no so
no that was maine was just like run the
program that was the old world that was
topics one through three
okay so here be dragons yes we're good
okay so so maine is kind of like and and
and
maine is just the first fancy pants and
people in chat
they're happy but maine is
[Music]
[Music]
um sorry
i'm just sorry i'm trying to a little
excited
okay snap back to reality oh there goes
gravity okay
okay yep professionalism all right um
so i if i re if i recall the sort of
metaphor
that i use to remember what main was is
it's
like when i specify certain behavior for
a script
when it is called as main in python
is that what main is acceptance c it
always starts at main
well that's kind of where python picked
up that main word from
um i feel like like this is
python's the millennial and boomer town
right now um
all right so you didn't have to walk
uphill to ways to go to school
you know what like dynamic typing is
kind of awesome
yes yes it is okay so here
we if i were to call add two numbers it
would be in main but i define
add two numbers outside of main is that
correct
uh i'm not a hundred percent sure i
followed that but
but try the truth so let's say so let's
say i write a script
where i want to define a particular
function to add to network you did that
in main i'll tell you right now so so
when i run this particular script
i would like it to print the results
whatever when i run this
thing whatever c's fancy word for this
yeah it's called program
right i want it to print the results of
add two numbers and i specify two
numbers
so i would define add two numbers
outside of main but i would
call it inside of main and print the
result
yes yep okay then i follow you i'm good
all right so
do what you just said oh crap all right
that's i mean you've got your function
defined
uh
[Music]
um i don't know if i can do this with pi
one step at a time let's let's let's
define a variable
and store the results
all right so just define yeah define x
now x is different from the other x
right
yeah because we're scopes different
right they're in different
stack frames
three and four
times
i know how to do this poop um um
hold please i think i think this
and then this and then that
all right oh lord do we want a new line
to just for fun
oh yeah yeah yeah except the other way
oh yeah because it needs to be at the
beginning yeah you've been in python c
sharp too often
no no no no let's do um what do you mean
i mean
oop oh lordy no i'll stop i'm sorry go
okay i will stop clicking things
this way backslash not front slash oh
windows backslash crap i'm sorry
that is a button i never press like i am
used to python on mac
and in a happy land where that
particular symbol i never need to use
so all right okay so try it out
oh no okay there's gonna be some sad air
oh
no no we got it hey hey
so i will tell you this whenever i write
a program not a script um
in any language but particularly in a
new language and also
you know decently complex in python if
it runs on the first
go and it's not as simple as add three
and four
i never trust it yeah like it's this
disturbing feeling of excuse me i just
wrote like 50 lines of code and they ran
on the first try
the universe must be broken and i spend
more time than i would debugging trying
to make sure that it actually did what i
think it did
because it's an it's an unfamiliar
feeling that's true and also because
it's important to me
you probably never got a heavy model of
what the computer is doing
that too but so we're starting there um
but uh let's um let's let's go a little
bit further oh and
equipollen thank you for the follow
sorry i missed that
um oh yay yes everyone who's from my
stream
follows some coding guy that's that's a
command from your
from your leader from dear leader
okay no no no no no sorry
no no politics
this is how we add two numbers so let's
fibonacci
oh no okay why
oh god because we got to start using
these functions right you know we gotta
all right let's how do we do
yeah how do we do a fibonacci sequence
it's just one i know it's like zero
one one two and then two it's just add
the last two numbers right you know so
it's
three right five and eight
thirteen and twenty one and thirty four
and
oh god they're twenty one thirty four
fifty fifty five and
okay anyway yes i had to remember how so
so we're gonna do um let's do it
we need a for loop yeah let's do a four
loop let's just do the first five
okay
miss tran i am not worried about
algorithmic efficiency at all i'm
worried about correctness right now
oh lord one thing at a time people
new language complexity step frame
algorithmic run time
big o is not entering don't worry about
big o don't worry about bingo i'm not
worried about
save space big o does not enter here
it's okay
okay the only thing we're worried about
is whether or not we're going to crash
because you're on an infinite exactly
this is sunshine and daisies
and and very good beautiful things give
me sunshine and daisies
all right so we're going to change this
we're going to call this look at this
shared selection see that
no hands thank you for making that a
thing it makes it
so much easier to follow you when you're
fucking without the stranger you're
slowly getting better
so no no you can leave x and y all right
so
actually um i was thinking about a
better a better a better terminology
actually you know what i'm just thinking
that's probably jumping too many steps
at once
let's let's no i got it i got it wait
wait wait before you do
you're got it let's um let's just print
out what
x and y are when it hits your function
no no but i can do the fibonacci
oh you're gonna you'll do it shortly
all right you want me to just print
print yeah it'll take you two seconds
something ah let's label our stuff come
on let's
x is wow we're in fancy pants
come on come on let's let's grow up with
our c programming
okay no more baby steps
peter pan all right um
put on your big girl pants now no i
refuse
i am wearing sweatpants that i fell
asleep in last night
okay um so let's try so can i do void
here yeah
let's start there hey yeah fancy all
right so
um compile error no no
no no no don't don't click it yet i
gotta fix some stuff so hold on we don't
need this
we don't need this the print is
already implied in my function so i just
need to yeah we don't want that
yep three for that
now see well of course it's it's pooping
itself
did i just spell it right yeah of course
stupid
but it's a word it's a it's a
sophisticated whatever expected before
token um did i forget i did i forgot the
little yep pedantic scene isn't it nice
we have errors too look at us errors
shared selection we're like crazy now
look it worked
okay great okay can i do fibonacci now
by the way what if we did that x and y
in one line
[Music]
um
oh i deleted the wrong i mean i want to
get rid of line six
get rid of line six no more line six
you did this before can i just do two of
them
i have no idea find out huh perfect
um you did you did toss the new line
let's i want that new line back
so well there you go you've got your new
line
all right fancy let's execute let's
let's clear
let's make sure everything's right okay
good um
all right run with it all right i want
to figure this out
so chat you shush i'm looking at you
yeah yeah
you can talk hang on chat but don't
distract yeah yeah you can talk to
people who know what they're doing
don't delete that line leave the line
i want the line all right i don't well
[Music]
um so let's see i want we are going to
have
i have an idea so just just let me roll
with this for a second
um so let me think about this for a
second
so the problem with picking an arbitrary
start number is you'd have to know which
fibonacci number that was
so let's just say rather than do that
let's just say
just do let's let's make it easy for now
we'll always start with
one yes yeah and we'll say how many
times we're gonna
so
i'll fix your other thing
oh wait no i can do that let's get out
of python mode
except they're not commas and c right
yeah i'm getting there hold on
sorry that's that's that's pseudo code
just give me a second um okay so
no nathan
oh yeah coffee with the crew is
absolutely right
this is where the music goes
so if it's one let's do some coffee with
the crew music
all right do you want slower fast
all right i think he's sad
that's probably really loud
that's really quiet isn't it
zero
it's fine
if the music's distracting tell me by
the way i'll stop it
it's fine oh i can't hear music oh okay
um plus equals itself
next time with two four
oh you kind of like to write like the
whole routine first right
make it hard what did i do you're
writing like
i i go way more iteratively i just um
let me show you like kind of how i
usually code something like this
rather than jump all the way to like you
know the answer
which is kind of like what you're doing
you're writing like a long like let's
get the whole routine right
right so i like to just i mean i've done
it i've done it in chunks too but i like
to kind of
take a whack at it and then if that
doesn't work i cut it down into chunk
because i do like to see because because
for me if i do it iteratively like how
you've specified
i often don't it's kind of like
something's holding my hand
and if i do it the way that i want to
fully
and it breaks i learn from how it breaks
and so i learned to build the whole
thing
better next time okay if that makes
sense
the problem i see is i'm not seeing the
program run
neither am i are you clicking execute no
you know what strophe i like setting
and it might just be that i'm at a place
in python where i feel comfortable right
but for seeing what happens learning
from it but
i definitely when i first started out
and i wrote like
i will do one line and test and print
what that line does and then i'll do the
next line and i'll print what that line
does
so i i definitely agree like that's
that's the cautious
approach that i've used but i
think our instance crashed oh no i broke
it
oh yeah cannot allocate memory
i think we probably had an infinite loop
run away
okay so hold on if if things are
loops are i that's my problem
no no the the runtime environment looks
dead
i think that's the problem
i i think that i think we killed the run
time
now that doesn't since i like using it
so it's that i made i made that mistake
yep
we killed it
i broke it right
i like breaking things i learned from
breakfast yes
i learned to not break them in the
future okay um i want to look at this
while you are fixing the braking
yes okay so
okay something ran away on that so i
have a feeling that
i didn't i didn't look at your loop too
closely but um
i think it should work again
oh yeah i see what's going on you you
have no terminal
this is an infinite loop
there is a terminal condition yeah
to what it's when this is less than or
equal to
well oh i need it to be equal too
okay okay well hold on let's let's go
with here i think that might work better
let's try your lessons no no no no
because that'll that'll fail from the
start and that's not what i want i i i
see the error there i want it to be
oh not that this either
as long as either is equal to loops wait
no this is the why
wait is this the the wild condition or
is it this is the terminal condition so
it'll stop
when this is when it's inverse of the
terminal condition so this is as long as
it keeps going
right so then this needs to be as long
as less than
loops yep okay right
so what are we doing with i then why are
we using either too
so so this is i is going to be the
fibonacci number iter is the number of
loops
so i specify the number of loops up here
in the argument function
iter is the number of loops
right so that's that's my sort of
relative placeholder for the number of
loops
my iterative thing and that's why i had
here
i had i plus equals i because that's
fibonacci right and so
i will loop and can consecutively add
eye
if you're changing oh okay until
i hit so then then i go here
and i don't know if i need to do this
but plus
equals one and then return
once this is all done we can have printy
printy happy land here that's fine
and then once this is all done my
function would return i
uh hold on that's in the loop so click
uh is it where does it oh i see i see
yes
that okay um all right let's try this
i will probably break i think our run
time came back
i am good at breaking things okay did
you hit execute
no i can't okay oh all right
uh like an error is better so let's see
first use this in the function
i okay because
i okay this is why you wanted to put it
you wanted to put your return in before
because i is only valid inside this loop
i see hold on no no no so i do no no i
don't want to turn it
no i don't i want to
and i know i know what you told me i can
define things it's okay you don't have
to
i don't want to in this particular world
because i want to be able
to i want to be able to no but i want
that to be high
why does it need no no that's the
initializer so if you're not
initializing anything then
oh okay so i don't i okay yeah you can
just omit it it's okay
got it i want that because i want to be
able to reference eye
guy is now available outside of the
scope of the yes okay
so go ahead oh no all right
more break okay let's see if we can
return with a value
and function returning void i don't want
this to be important
yeah poop on you all right expecting me
oh i need semicolons everywhere
or i get sad all right um
so okay right that
actually hold on no so
fibonacci we call fibonacci three here
which we would expect
two is the answer oh but i need the
previous one so hold on i
equal give me this hang on
hang on i got this so there is the eye
of the loop and the eye of the previous
so
i by the way i hate fibonacci problems
i'm sorry we did this no no no no i want
to pick i want to
so hold on let me let me ramble to
myself for a second so
the issue here is that we're adding
when we get to two we're adding two to
itself instead of the previous i
so actually what i'm going to need to do
is i'm going to need a way to store
the previous i value
in so yes here's what we need
so we need to start out with
i'm going to bring this up here yeah
so we need to start out with
i'm gonna start an easy land i'm not
starting with zero all right um
so i plus equals
previous i and then here
previous i
equals i
poop on you poop on your face all right
let's walk through it
so because i want to get done with
fibonacci too
so um okay so you're using
iter zero so first of all this is only
used in the loop as an
iteration counter so why don't we just
move that here
okay um oh
right oh what oh okay yes that makes
sense
actually so let's just keep the
iteration so this is going to count
however many times we have it's going to
run our loop
however many times loops is right so if
loops is one
then it should just do it once
okay so if we do loops of one
execute okay so it prints out only
once yep okay cool
so that's fine so if we did two you were
gonna see two lines that's the correct
answer
okay so that's
one two no because three so one loop
would create two the second loop should
create
three um
yeah so ah i see the problem um
hold on give me one second here so i
plus equals previous i so that
instantaneously becomes two i need a way
to store
wait that can't work can it can that be
the thing that i want
well i mean hold on the line we really
want
let's not be fancy for a moment if
you're you're using i
as the current fibonacci number right
yes
yeah okay so the thing we really want is
i is going to get
whatever the previous number was
plus whatever the number before it was
the previous previous i well i mean you
know two
is the example two here is equal to
i love being able to name variables
me yeah
i mean we could use one of those as the
current eye if you want to stay on like
the current one and we don't want to use
two memory locations so that's okay
um so it's gonna be whatever
i was at the start of this loop
plus previous i
yes and then previous i is gonna become
that's what i thought i was doing wait a
minute
that's what i just did okay so
previous i plus i
see this is uh you built yourself this
this this terrible terrible you've dug
yourself into a hole here
fibonacci is yeah i know
no it's good it's good we have to reason
through this okay so we got this
yeah we could figure it out okay so
um i is
where are we changing i
we're adding to whatever the previous
side so
if we started i off at one which is kind
of what you have here i'm gonna
move that down here right um
so i starts off at one previous i starts
off
also at one
right okay so that yeah i should have
put my
other thing up there okay so
um so initially it makes sense to have i
equals previous i
think our issue when we update yeah
when we're updating yeah so we start
these off at one
one plus one is two so um
great we get we get the right number and
now we need to move
this eye to be this one because when
we're here when we're sort of like
doing one and two and i know you can see
selection now
i can this is so nice then if this was
like
i then we're gonna take this thing
plus previous i to get this
and then we need to move previous i to
two
right i thought that's what i was doing
before but i must have made something
yeah but we're overwriting it
at the same time right yeah okay i see
what you're saying
yep
okay so yeah we can see we can't it's
like right here we just overrode it
so we can't right so so let's let's
let's i'm trying to make all these
things into two
too many too many fancy pants lands okay
that's so how about we go
all right that's okay you know no just
for now because this is
also this you want to talk about like
ways to do things because i
write things the worst way possible the
first time to bring forward
and then we can be optimizing i'm not
worried about that right
yeah so now we can say previous i
equals i and then
i equals new i
okay that's not the greatest way to do
it but i'm like
iteration is already being incremented
because that happens with the loop right
right so why are we doubling but that's
just
we're no no we're not doubling our
iteration we're just
no we are yeah nine nine
we add we add to it each time
and then in line 13 we also add one to
it so we're adding two
each loop oh no this is c land okay i
don't have to spell
right we're good right yeah so that just
does it it does it yeah that's that
happy little part of the okay all right
that was python me i'm sorry that's okay
that's okay we gotta go
we gotta make see you
okay we're in sweat pants mode not fancy
pants precisely
okay actually i'm going to be right back
really fast um don't you want to see if
this one's then we will
i want to okay fine let's see if it
works
[Laughter]
all right now be right back all right
all right i'll catch up on chat because
i'm totally out of it okay so don't
forget we're in sweatpants not fancy
fans yes
trophy that's yeah it like try to do too
many things at once and it's easy to get
kind of messed up uh insulators what
you're doing is right but there's
another problem try passing fibonacci
value like 10. yep not worried about um
iterations i'm not i'm not sure if that
refers to the previous version of what
we're looking at right now
um so
it is what you're doing maybe guy hasn't
seen what is wrong oh yeah i wasn't
looking earlier nathaniel sorry about
that i was actually just looking at the
resource problem when the
the loop ran away i think it ran away
while she was writing
not um with her end program but at that
point it was already non-responsive
like i mentioned i really need to get
job control um
i'm playing architecturally i'm sort of
messing around with this i want
to not continue down the path of running
everything on the server that was just
kind of like to get started quickly but
i think that um the future version of
this
is um it's going to be more peer-to-peer
as opposed to like client server which
is kind of what i have right now so
i want like you know somebody's going to
be like running the compiler and
somebody could be you know
typing and you know that that kind of
like groupware type peer-to-peer
collaboration rather than the classic
client server model
um so try passing
yep you can initialize either inside the
for loop yes that's
true um
yeah okay so i think i think we're
caught up if i didn't miss too much
uh and sorry about the
music i just paused it the whole world
is in sweatpants mode totally
is that thing compiling to native or in
scriptin it's compiling to native at the
moment
i was working with the inscriptin so the
problem is you have to get it to
self-host
in scriptin and llvm is massive miss
tran
i don't know if i'm saying your name
right by the way
yeah that's so that's kind of the route
that i was going with him script into
wasm
but self-hosting and scripting is really
nasty our guest
is uh the enceladus source oh she's back
hi yeah i was testing so stropham had
said try
a larger a larger value like 10 and i
would just like to demonstrate
that my super awesome fibonacci function
in c does actually work i think i don't
know really my fibonacci number
that's like 21. that's close enough i'm
not i'm not too worried about it but
um the runtime of this is not too bad
because um this is basically just gonna
do one for loop
um which is fine i mean if we if we were
doing something a little crazier with
like
you know the general recursive version
of fibonacci then
this quickly runs away but we already
had the program run away once on us
um and miss yeah no that's cool um that
uh you're curious because that this tool
is by the way open source
so we'll we can talk more about that in
the q a i'll put that down as a topic
how cool the thing that you built is yes
please can we make that a topic because
this thing is amazing and like i keep
you know not so subtly being like when
is this like when can i start to use
this with the people that i'm
mentoring because this is incredible and
if i could do this with my little
brother
and some folks at work that i'm teaching
how to write in python like
my gosh yeah i mean funny that you
mentioned that because if you look at
this drop down in the top left
my god i see c sharp there
i added a few more run times um
i realized some issues with java and c
sharp
that really has to do with the way
classes work and it really those two are
very early version because they they
really need multi-file support which i
haven't added yet so the ability to use
more than one i need like a little file
system navigator widget for this but
um anyway we're heading there okay
let's let's get back to functions so
enough fun with fibonacci
fun we're going to call that fun how's
that
so i will i will save this anecdote for
our after hour
scotch stream but i do want to just say
like
ask me about my office mate chad so if
you remember when we get to the
after hours portion ask me about my
office mate okay
office mate because i i see okay this is
this is
there there are revelations happening
for me okay sorry
as i learned all right but yes let's get
so i think it works
yes it looks good to me i like it um
you can save this by the way if you want
to yes uh give me one second to
copy this into my new throw it away
oh yeah shared selection showed up on my
screen
i see it on stream now wow here we go
okay awesome thank you because i do like
to say what we write and talk about and
i have a bunch of notes
kind of commented out on in my in my
note file but i love to copy and paste
what we do so that next time i can kind
of remember totally
totally um i'm gonna say a little bit i
don't
we're gonna save um i had a whole long
thing about
the actual layout of the call stack i
think we can
table that i think i think i think we
did kind of enough on the call stack but
um the important thing with the
uh i'll add one more
we'll just whiteboard this instead of
going into the what i was going to show
you before
so let me just flip back over to uh
the whiteboard and
this thing has okay so we just did
our first like function and it defined
its own
call stack so i had
main down here and that's a great m
and you know what let's let's switch
colors what what color pick green
green now we already do you only get one
one use per stream right purple purple
all right my second favorite color is
that that's probably too dark for stream
oh god well i mean this is it's kind of
magenta-ish but
um so lavender all right now we're good
let me know chat if that's too dark so
um so we had main
and we had um fibonacci
and these what did fibonacci take for
parameters
and what did it return so fibonacci took
a single int for a parameter and it
returned an
end so in that particular case i felt
like it was
not one of the examples that i was
concerned about
and what did we have in fibonacci
in fibonacci we had in addition to the
specified argument loops which was an
int and the return
i which was an int we also had one two
three more ins okay so they were
i so i
was yes that was our return we returned
so we already kind of specified that at
the beginning and we had
previous eye and new i
and new i
but the return when we said int
fibonacci at the beginning
that return that you said there yeah was
i we returned
i so that's that doesn't matter
duplicate no um because
the return type the reason i say that is
because the return type
doesn't have a name you'll like you'll
notice in line
four where you specified it i'll just uh
jump back to the uh
fibonacci yeah i see it yeah so chat
yeah just for chat um
so sorry friends it's okay in line four
you'll notice this
doesn't have a name right so it the fact
that you choose to return
i just means that i needs to match
whatever type this happens to be
so like you would get something a little
bit funky if this was like
if if we defined i as a care
yeah you know and then um care i and
i don't exactly match but it it can be
so what does that end at the beginning
do because when we first
discussed what that particular line did
oh
lord i don't want to think about what
that did that hurts my head
what i yeah we wrapped around into the
sign area
okay no that actually makes sense given
your explanation so i'm fine and that's
why we
like to mind our types because seal try
to interpret it
what is the point of declaring what the
return type will be if it takes more
memory
to specify that return variable
i thought that was like setting aside
it's like it's like staking off a little
portion of memory land
this is what you get for returning and
when i return eye it's like oh well
i've staked this off for you so use it
but apparently from your diagram that is
not true
it's not exactly true i mean it just it
just says that
um i mean you have i which is
a local you're talking about an
optimization right
you're talking about if um the compiler
was smart enough
to say this i that you declared inside
the function
is only going to be used as this return
so we would have to analyze the entire
function to know that
this i is really just going to be the
return value
right because the way my compiler is not
smart
well it depends on your compiler to be
honest
actually a smart compiler is going to
destroy this entire routine so we're not
we're
let's not get into optimization
compiler so we're not going to worry
about that
um so in in the classic literally in
what you wrote
there was a return type which was an int
so how big is an int
for our purposes
32 yep 32 what's bits
okay which are really bytes now we're
four bytes okay so we're doing four by
type okay so we're going to allocate
four bytes here on the stack
okay loops was what type
loops was also four bytes integer
okay so actually here let me clean up
this diagram
okay so we had some stuff i'm not
worried about main
and then we had um so
in the blocks that we sort of blocked
off for fibonacci
we had return which was four bytes
this is the return value and then we had
loops
which was what it was four bytes you
said same yep
everything is pretty much int and then
we had
i in the non-optimizing case which is
four bytes
and because it's really just an ant and
we had iter
which was also four bytes now
yes um we could have used different
sizes for these and if we didn't worry
about alignment then we could have said
like you know
maybe i was just a care and that kind of
got us into trouble
because we actually overflowed how big i
was we could have used an unsigned care
and gotten a little bit more leeway
enough for our particular example but as
soon as we started increasing the number
it would be out of control pretty quick
okay so this stack frame
needs how much room
eight two outside of main
32 yeah bites yeah this
this stack frame is 30 this is a 32 byte
stack frame
now the only other thing that i told you
that there was a little bit more
right okay and the important thing that
we're going to talk about
in that little bit more is
what does the function need to know when
it's done what does the computer have to
know when it's done running this
function
this functions specifically or any
function are you abstracting okay
when a function finishes where does it
go back to
where
do you mean the sound of one hand
clapping
so so i have a couple of thoughts so
when a function finishes
well i mean in this particular program
that we just ran
i mean fibonacci was called on line 20.
it it returns to maine
yeah i mean it it just ran when it ran
line 20
it jumped up into this new stack frame
that we just drew
and when it finishes in that stack frame
and it gets its result where does it
return to
the previous the the stack frame that
you the the
aforementioned stack frame yeah it has
to get back to
basically line 21.
line 20 yes line 19. yeah the scope
that is line 19 to line 20 well no that
that's that's the scope but i mean the
fibonacci was called on what line
20. so next line after it
21. yeah that's i mean it sort of has to
return
like you know where to go
so yeah i mean where to go is just the
next line
right yeah and that's actually that
little bit of memory that i just
mentioned
um sometimes there's something else
which is like the registers
are stored there um it depends on the
particular compiler and some other stuff
that we're not going to get into but
so that's the little bit of stuff that i
was talking about before
but you can the compiler can exactly
this isn't guesswork it's not
it's not like your notion of python
right i mean it it
it's not like just loosey-goosey saying
oh you're going to get this
astronomer i love my back of the end by
the way i love python i'm just telling
you that like
it's very deterministically saying like
your memory
goes from here to here and that's it
that's your stack frame
and when you're done you go this you
have to go back
right you have to go back to the next
line and
that and then we need to return the
registers back to their normal state and
some other stuff
depending on the particular architecture
strophium
we're going to talk about this later my
friend we've already had our our
philosophical
differences aired to all of chat so
okay doesn't love python wow okay sorry
you know
the trail but we're fine before you get
to that last topic on this
okay yes so that is
that is a picture of sort of a c stack
frame
is that the only way you can write it no
because you have
also said that there are frames that
right bottom
up and it depends on the architecture we
have built something that looks like
intel architer architecture if i
remember right which is
top down right okay so we
have a choice we can have the stack grow
down
in memory so this would be like if we
have only 256 bytes of memory
so this is a really crappy computer
then maybe this is like the calculator
that uh i think
who was it in chat was it nathaniel who
was doing miss tran
um so if we have 256 bytes of memory
then the stack might be at like you know
255
growing down you know and then however
many bytes were
needed is going to be your main and then
however many
bytes are needed is going to be your
the function you just wrote fibonacci
and then however many butts are needed
for any other functions that you might
call
and that's fine until you hit zero right
right all right we just used all of the
computer memory for
stack which leaves us no space for
actually running the program
exactly and it leaves us no space for
libraries and it leaves us no space for
heap and
all sorts of other stuff so this stack
has to be sort of a fixed size
and when you grow past the size of your
stack
crash right and you mentioned that
earlier when that
that like the bottom and the top meet
it's it's it's
it's uh oh time yeah yep we can talk
about the heat memory growing up
we can talk about libraries that might
be mapped and some other stuff that's
kind of in the middle
um there's a lot of choices we have
we can also say in in our parameters so
like for example add two numbers
and we gave it an x and a y
how do we put those in memory
what do you mean we can put we can go
left to right so we could start with x
right so if i'm if i'm looking at my
stack frame i could say like x goes here
and then y goes next
okay right or i could say
that's going left to right or i could
say let's go right to left
and we're going to put y first and then
we're going to put x under it
okay this seems like this seems like
convention this seems just like
that's exactly what it is so i can put
the return value up here
i can put the return value down here all
of these things
get into the convention that i'm going
to use for my calling
and that's really important because
when you're in c you're typically using
something called the c declaration
style which is right to left
and the stack is unwound by the caller
so it's right to left and it's caller
unwound
so like the job of sort of like what do
you do when this function's over who
cleans it up
does the function clean itself up
its own stack or does the thing that
called it
clean it up
the
it's a conventional ladder right like i
would i would guess
but actually both is the answer
it really depends on what you're using
for a convention
it gets to exactly what you were just
saying okay
so i mean this is kind of like
my my linguistic intuition here
about conventions of dictating
language in terms of human languages
seems to apply here where this is
all just convention yeah i mean okay
referential convention which c was sort
of
being built around the same time it was
left to right
and the callee cleaned it up
makes sense i mean i don't i mean so
so in your example no no it's okay i'm
just saying like i'm just telling you
like you know
if you did add two and pascal it would
be like
you know and it was x and y then on the
stack it would show up
like you know x first and then y
second you know if the stack is growing
if we're on an architecture where the
stack is growing down
in c declaration it was right to left
and the caller was responsible for
unwinding the stack
the reason they did that is they
basically the problem is
functions like printf so how many
functions how many arguments does printf
take
printf takes two arguments
no it takes as many as you specify
because you can do we actually just did
this earlier which is why i didn't want
you to delete it
well one one is one is mandatory
two plus are optional
true but how many is that yes
two plus two infinity we don't know
right
yeah it's like two dot dot dot yeah i
mean in this case
we're calling it with three functions
sorry three parameters we have
the specifier we have the x and the y
that match up with the specifier
if we just did printf and hello
once we only have one right right
so this is called a variatic function
because it has a multiple like it could
it could be like you know one it could
be two it could be
50 whatever right so
however the stack ends up getting built
the callee
never really knows in this case and by
the way you can't write a function like
this in pascal
it's illegal because the the
printf itself doesn't know how many
arguments you're going to pass to it
right
yes i mean it
knows in theory in terms of how
it is defined in its own documentation
like wherever printf
is defined it knows that it can expect
mandatory one optional two to infinity
argument no no but i'm not talking about
in its specification i'm talking about
on the computer
how do we unwrap how do we unwind the
stack frame
i mean however many you call it's it's
sort of up to you when you're making
that call of print f
you might pass it three you might pass
it two you might pass it 17.
it's up to you right so
yeah printf itself has no idea how to
unwind the stack
so
then what does it it the thing that
calls printf
so if i have main
and i'm calling printf
with you know these two parameters
right when i'm here i know exactly how
many parameters there are
yes okay but when i'm in this thing
i have no idea what do you mean by when
you're
in this thing like if i'm implementing
printf
like if you had to write the print f
function
you're inside print f
just do some like len argument stuff
what do you mean len
which part of memory are you gonna lend
you're not passing along a description
of memory also
you're just passing along okay here was
the first thing which was this
string which we're gonna i'm skipping
over how to how that's represented in
memory
and then here was the second thing
actually it's c so it's backwards it's
right to left
so it would be here's the here's the
thing and here's the
percent d thing
as the stack is growing down so inside
of here
how do we know how many there are
at what point have we crossed into the
next stack frame
like somebody else's function
we have no idea where this line is
yeah well i'm good i'm glad that there's
a
yeah okay i mean so we could change our
language and say okay
you always have to pass how many
arguments there are going to be
so there are two arguments right
this uses a lot of memory and now if
we're in python we don't really care
right
so and that is kind of how your len
works you know in lines
in languages like that like that's
that's pretty much how it does
it works in javascript right you pas
there's there's something called
arguments
and it's an array and you could do
arguments.length
and it'll tell you like yeah you got
this many parameters but
c is just literally representing memory
so if
if you've done this there's nothing here
to tell you how many arguments there are
i don't like that well i mean that's
reality
i know i know i'm just like processing
it that that bothers me
but okay so that's actually the reason
why
in c they wanted to have this support
for what were called
variatic functions which could have a
variable number of arguments
and so then they said all right well the
way we're going to solve that we're not
going to use
more memory storing you know the length
kind of like that you specified instead
they're going to say
you know what we'll just make it the
caller
unwinds so it's the job of the caller
whoever
calls printf it's the job of the caller
to unwind
the stack and to clean up the mess
aka it's your problem not mine yeah and
that is the c declaration
or user beware okay declarer or beware
yeah pascal was like no no the callee
unwinds the stack which means you don't
get to do a variatic functions
you know that's kind of the world that
like c was being created in
so you know that that's like and also
things were
left to right so when we're assembling
this thing and putting it onto a
particular machine
we could actually look at this and say
like all right this is how when you call
this function
pull x here you know take x from here
and take this percent d
thing from here and in c you know we had
to we had to flip the order because
we're doing right to left
um and there's some other speed ups
by the way this is what microsoft uses
so windows uses basically a version of
the pascal calling convention
which is to say it it's call e
unwound except it's right to left like c
just because windows hashtag windows
hashtag windows
so it really does matter like what kind
of c compiler you're on and you know
whatever in terms of like how it's
represented in memory
um the name for that is called standard
call
because microsoft likes to call things
standard
but even though that's actually the real
standard is the c declaration syntax
so and the funny thing is c actually
allows you to specify
all of these so you can actually
tack on to a function pascal
int add to
you know x and y
and c is gonna follow pascal calling
convention
thank you nathaniel by the way
so these are a little bit more of
keywords that are available in c
they're there kind of historically c
functions had to be able to call pascal
functions
c functions work differently on windows
than they do on on
linux or different unix operating
systems and
basically the standards committee just
kind of said well just if you don't
specify
you're going to get c decl you're going
to get c style declaration and
if you do specify then you're going to
get
you know maybe standard call if you're
on a windows it'll be defaulted to that
or you know back when you were writing c
code on a mac
all of the mac roms were all implemented
using pascal calling convention so you
had to literally type pascal in front of
every function
whenever you were calling into the
operating system so that sounds very
much like my
max so i'm sorry for laughing but that's
you you had to do this
like you know so
you know that that it's still valid
syntax you can't really take anything
out of the c
standard so so it's all there but i
don't think
anybody would probably use pascal
calling convention mostly it's just
down to standard call which is you know
kind of a windows convention and
linux the world that we're running in
right now which is using the standard c
declaration
convention all right make sense
70 confidence uh
areas for questions it's it's more i
would say
it's kind of like it's practice yeah
yeah exactly that so it's when i learn a
new language and
uh humanly and a new grammatical
construct is introduced
and i feel yes i understand it but i'm
also concerned that the second that i
leave this class i won't remember it
that kind of hesitance
so that 30 is more of like experience of
learning things telling me oh sure
you need to practice this to remember it
yes so like
i'm confused that i totally accept that
i'm not asking if you will remember this
forever
that that'll just take practice um but i
mean like
overall it's not like you're listening
to any of this and you're going ah no
way why would you have different calling
conventions it's like
well people just don't get along i don't
know i mean
it'd be nice if all these things were
standard and they're more or less
standard now
um and we're going to get a little bit
into the stack later
like we'll get into the stack when we
get more into like heap space but
um yeah you could take any strophem says
you can
you can't take anything out of c you
could just make fun of people that use
yeah that's pretty much how it works in
practice is exactly what strophium just
said
um you you can like
that those keywords are going to be
there forever like
and that's part of the reason the see
standards committees these days like
they're so
anti-adding things like you wouldn't
believe how many years it took to get
this slash
syntax added for commenting
we're not gonna get into that i think
we're
safely done with our topic
okay i mean i'm i'm i'm happy look at
this i wrote i wrote i wrote function
it did something it required a little
bit of tweaking but
in the end and i remember the first
python function i well i don't remember
explicitly what it was but i do remember
the first time i wrote something and it
did the thing i wanted it to and it felt
like victory so which is awesome there
is an important thing which is that
this is part of why i was going on about
stack for so long what happens to things
like previous eye
and iter when fibonacci
ends
i would hope that that is freed up yeah
they're thrown away
that's that's unwinding it's a relative
reference
i can't come down here in like line 20
and go to 21. i can't say previous eye
plus 5 or something like why can't i do
that because that's a different stack
frame
that's a different scope
that stuff has literally been thrown out
by the caller
make sense yes and and that makes yeah
the scope and
yes we're good okay so
i think i don't want to give you the
trick question
which is oh no how do i return two
numbers from this function
what do you mean like right now i'm just
returning the last fibonacci number what
if i wanted the last two fibonacci
numbers
i'm guessing it's not into common int i
or
fibonacci but that's pretty good
intuition to be honest
it's it there isn't syntax for what you
just described
but okay there is something like
what you just said um do i just allocate
double the memory where because
anywhere you'd allocate it inside this
stack the only thing that's going to
come back is return
here uh yes
so i make that double and then i return
i comma whatever
okay so one option would be if we knew
that like
long no tuples in c night shade dude
hell
we could do something like this and you
know we could say like okay the first
you know if a long long is twice the
size of a of an in
then we could take the top 32 bits and
make it the first value and the second
32 bits and they make it the second
value
it's kind of crazy isn't it it's
uncomfortable
yeah that's um that's called a bit field
i'm sorry i literally made a joke
earlier
so now to realize that okay
we're good it's just i was making a joke
about
oh well and c 2000 or something we'll
have long long long
we're fine but
that's totally fine uh so we can use the
bitfield approach um
really like there's a couple different
answers and one of them is going to get
into what we call
pointers um which we're not going to
cover today
uh but that's a future thing and that's
actually kind of where this syntax
appears from by the way this line 19
stuff
okay so pointers are a way to kind of
break this model and allow you to reach
outside of your scope
um and another way we could do it is we
could build oh no pointers
we can build pretty much what you just
said you know which
we want to return something like a tuple
right
well i was just told there are no tuples
no there's no tuples directly but
there's something like a tuple it's
called a struct
oh no trophium no
sorry this this happened yesterday where
he's like well you've learned about
struxxt from c and i was like what's up
yeah no we didn't cover stocks
and a struct is just a structure which
is going to be like
num1 num2
and i could return a struct fib returner
and that would be basically kind of the
c equivalent of your tuple that's about
as close as you could get
but we're not really going to get into
structures today structs are all about
compound types so we're going to take
our basic types and sort of
put them together that's what a struct
is for so well is that is that a preview
it's like next time
on that's a preview strophium teaches
just how to write c
strucks okay all right as long as this
is a preview of next time and not
something that you expect me to
no this is disturbing so i will
it does lead to a problem because the
problem is this whole stack model that
we just discussed which is like there's
only one spot for a return value
so that's like how do we
now i mean the there's there's enough
ram there but there isn't a direct way
in the language to say i want a tuple
like i want to return two of these
things okay
so i think that's pretty good