COLTON OGDEN: All right.
Hello, world.
This is CS50 on Twitch.
My name is Colton Ogden, and
I'm joined, once again, by--
NICK WONG: Nick Wong, hello.
That is my name, actually.
Sorry.
I guess I should start with that.
Oh, well.
COLTON OGDEN: What are
we talking about today?
NICK WONG: So today we're going to talk
about C, not C++, not C#, not Python.
COLTON OGDEN: A lot of
C languages out there.
NICK WONG: C, yeah.
COLTON OGDEN: But C is like
the progenitor-- progenitor?
NICK WONG: Yeah.
Progenitor, I think it was.
COLTON OGDEN: Progenitor.
These are the old fashioned ones,
very simple, very lightweight
programming language.
NICK WONG: Yes.
COLTON OGDEN: And today--
NICK WONG: Fast is how it works.
COLTON OGDEN: --we're not
going to-- yeah, very fast.
We're not going to be talking
necessarily about the stuff
that we cover in CS50, though, right?
We're going to be doing
maybe more of a deep dive?
NICK WONG: Yeah.
So we will open up GDB, which
is the debugger for CS--
sorry, for C. Yes, for all of CS.
COLTON OGDEN: For all of CS.
NICK WONG: A granddaddy debugger.
We're going to walk through a little
bit more in depth than CS50 does.
Although CS50 does talk
about things like Malok
and memory spaces and things like that.
But I will also kind of be a little bit
clearer on stack versus heap allocation
and why one was important,
why the other one is not--
sorry, why any one is
important at any one time.
We'll talk a little bit about
buffer overflows and things
like that, as well as how
input-output standard I/O works,
because I think that's really cool.
COLTON OGDEN: Yeah, yeah.
No, except low level, to a lot
of people that are maybe not
super familiar with CS50 might
think that means very basic.
NICK WONG: Easy, simple.
No, no.
That is a great misconception, I think,
where a lot of programmers will say,
low level, high level,
and then people are like,
oh, I want to learn high-level stuff.
And generally, that actually seems to be
kind of true in the modern day and age.
A lot of people do like to
learn high-level things.
But that is not because it's
harder or cooler or anything.
High may kind of refer to, if
you imagine a computer system
as at the lowest level, you have
hardware, and at the highest level
you might have a graphic interface,
and everything in between
is kind of organized.
Then that's what people
are talking about.
So in the lowest level you have this
literal, electrons running around
in, like, a piece of metal.
If you wanted to kind of vastly
oversimplify and humorously
oversimplify what's going
on, we basically took a rock,
tricked it into thinking,
and then electrocuted it.
And that's the computer, right?
That is a computer's lowest level.
And then right above that,
you have this kind of--
and we'll skip a few levels, just
for the sake of time and clarity.
But there's basically machine code,
and we'll kind of approximate that
as assembly, which is basically--
I'll show a couple of examples
of what that looks like.
But the instructions, they're
roughly one-for-one instructions
that a processor will execute.
And I say roughly, because
that's not entirely true,
but it's the right concept.
And then maybe one step
up from that, we might
have something like C, which is
then going to be compiled down
into machine code or assembly.
And then that will get
interpreted in some way.
And then maybe above that
you might have something
like Python, which actually ends
up kind of running on C. I mean,
it depends on the runtime you pick.
But it could actually be run through C.
COLTON OGDEN: Use C to
compile the program that
executes the Python scripts, basically.
NICK WONG: Right.
Exactly.
Cool.
Awesome.
COLTON OGDEN: I'm very excited
to dig into this stuff, because I
know C is a very popular language,
or has been historically,
for game development.
NICK WONG: Right.
COLTON OGDEN: Assembly
before it, for the old--
to tie back into, like, our NES stream.
NES was really in 6502 assembly--
NICK WONG: Oh, that's brutal.
COLTON OGDEN: --a very
common older microprocessor,
still in use for small
devices, but not as much
as I think more RMCPs these days.
NICK WONG: Yeah.
COLTON OGDEN: We have a
lot of people in the chat.
I just want to shout out everybody
who's joined us here in advance.
So scrolling way up, we
have a lot of chat here.
So [? TwitchHelloWorld-- ?] that's
[? JacksJPGuys, ?] [? ISOTV-- ?] let me
just keep scrolling here. [? Brenda, ?]
[? RealCuriousKiwi, ?] was in the chat.
I see [? NonBored. ?]
Thank you for joining--
[? Asley, ?]
[? Nowanda353, ?] as always.
[? John09JLardinois, ?] thank
you very much for joining today.
[? VippleBHJ ?] and
[? Bhavic Knight-- ?]
[? Bhavic Knight's ?] a
long-time regular as well.
Let me just make sure I
haven't missed anybody else.
I think we had [? LKit57 ?] joined us.
I don't recognize that name.
I might just have a terrible memory.
But I hope I don't
have a terrible memory.
Thank you very much for joining
if this is your first time.
If not, I apologize. [? OoeyZuck, ?]
Thank you very much for joining.
[? GoldenKappaChick-- ?] I'm not
entirely sure what that means.
But I appreciate it.
Thank you very much.
Oh, we've got a lot of Kappas.
Maybe that's what-- maybe they're
trying to do a Kappa test.
NICK WONG: Yeah.
COLTON OGDEN: Test and
see if Kappas are working.
OK, [? JLardinois ?] was talking about
[? AnnFogleman, ?] craft projects,
this is like the Minecraft
C port, which sort of ties--
NICK WONG: I see, yeah.
COLTON OGDEN: --into this conversation.
He's saying he found a
really good use for--
it looks like switch-case.
NICK WONG: Switch-case and break.
Nice.
COLTON OGDEN: Switch-case is a very,
very common puzzle piece to use in C.
Everybody's hyped--
phones less delayed than PCs.
That's interesting-- higher
the level, more abstractions.
NICK WONG: Right.
That is a great way of
putting it, actually.
COLTON OGDEN: Yeah-- obviously trying to
manipulate the Silicon directly with--
it's just you're going to be less
productive than being able to write
a Python script, for example.
NICK WONG: Right.
Exactly.
COLTON OGDEN: So different
layers of abstraction
allow you to do different
things more or less easily.
MoHelat says, what can we
do with the C language?
NICK WONG: So that's actually
a really interesting question.
In talking about any--
they're called Turing-complete
languages-- so basically,
any programming language
you can think of--
you can do anything.
Anything that you can imagine
being done with any language
can be done by any of the other ones.
So if I can do it in Python,
I could also do it in C.
I could also do it using
only NAND commands.
Technically, there is that possibility.
So generally, what ends up happening
is, when people say what can we
do with language, or what do
programmers do in a language,
they generally mean a little bit
more like, what's convenient?
So what things have been written to be
really, really good in that language?
What things have a bunch
of APIs or libraries?
I guess, what has the language
been really specialized for?
So when someone says that like R, for
example, is built for biostatistics,
they mean, really, that there are
a lot of developers who are in bio
and do a bunch of biostats
who develop for R.
And those people are going to
be a great community for that.
They have a bunch of resources.
They'll answer all
your questions on it--
all sorts of things.
But that is not necessarily going
to mean that you couldn't, in R,
build Minecraft, for example.
In concept, you could.
But whether or not you'd want to is--
I mean, I would argue you
probably don't want to.
[LAUGHTER]
COLTON OGDEN: That'd
be interesting to see.
NICK WONG: Right.
COLTON OGDEN: I'd be curious
to see how somebody does that.
NICK WONG: --or like, a
neural network in OCaml.
You can do it.
It would not necessarily be super fun.
Whereas in Python,
It's pretty convenient.
And so these kind of choices-- they're
based on convenience and comfort.
COLTON OGDEN: People have
done a lot of hard work
making libraries and
stuff like that, too.
NICK WONG: Right.
Exactly.
COLTON OGDEN: --people that have had
an interest in solving these problems--
NICK WONG: Yes.
COLTON OGDEN: --put that
hard work in in advance
to make it easy for everybody else.
NICK WONG: Exactly.
COLTON OGDEN: [? GravyWave123 ?]
says buffer overflow.
NICK WONG: Yes.
We will talk about that, actually.
COLTON OGDEN: Why is C considered
so fast once it is compiled?
Wouldn't any compiled
language already be
compiled into binary, so
therefore run with the same speed?
NICK WONG: Sure.
COLTON OGDEN: So that;s
[? TwitchHelloWorld? ?]
NICK WONG: That is a great question.
So one of the things is that the
developers of the C compiler--
if we're talking about
CC or Clang, then that
has been just so thoroughly developed.
It's a brilliant compiler.
And we'll talk about compiler
flags a little bit today.
And I think that--
there's a funny story dealing with
compiler flags and the speller piece
in CS50.
But basically, the builders of
that compiler-- the architects--
designed so many, just,
brilliant techniques
for compiling from the C abstract
machine down into assembly
that that ends up abstracting out--
or I guess not abstracting out,
but cleaning up a lot of
your C code once you've
written it, to make it faster.
And one of the other
problems that's faced by--
maybe you built another
compiler and it's just as smart
as theirs, except maybe your code is
like Python, where it's interpreted.
So every time I run it, it actually has
to interpret the code that is being run
and then compile it as it goes.
So then that interpretation
step actually
ends up taking up a
bunch of time, as well.
And there's a couple other reasons
that deal a little bit more with how C
integrates-- or C, C++, C#--
all integrate with--
I guess integrate's the wrong word.
It's not exactly what I'm looking for--
don't have as much
overhead in what they do.
So for example, Java requires
the entire JVM in order to run.
And that's a lot more overhead than
C, which is literally just executing
instructions.
So there's all sorts of
interesting things there.
There's a lot more complexity to
that than I will be able to answer--
and probably--
guaranteedly more than I know.
[LAUGHS] But those are some reasons
that come up to the top of my head.
COLTON OGDEN: Yeah.
So abstraction, in a lot of ways,
you're paying for performance.
NICK WONG: Right.
COLTON OGDEN: Obviously electricity
flowing through a rock--
NICK WONG: [LAUGHS]
More performance.
NICK WONG: Very fast.
You might not understand
it, but it's very fast.
COLTON OGDEN: And to your
point about NAND gates--
I think it was watching a video
recently on Computerphile or something,
where they were talking about how
transistors are purely built off
of just NAND gates, which
I thought was fascinating-.
They wire them together
in this weird way.
And that's all you need to do--
NICK WONG: You can do anything.
COLTON OGDEN: --to implement it all?
That's so fascinating.
NICK WONG: NAND on its own is Turing
complete as a single instruction.
For those of you that are maybe not
familiar with NAND, it is not of and.
And basically what that means
is, if I put in a one and a one,
then I'm going to get the opposite
of what and of one and one is,
which is one.
So I get the opposite of that.
That's zero.
And then if I put in a one and a 0, or
a zero and a one, or a zero and a zero,
those are all zero when I do and of
those three-- of those combinations.
And--
TOGETHER: That is going to be one.
NICK WONG: Yeah.
So NAND literally only has one
case in which it returns zero.
The rest, it returns one.
And that allows you to do anything
a modern computer could do--
COLTON OGDEN: That's outstanding.
NICK WONG: --which is crazy.
Although it can maybe result in
millions and millions of lines of code.
Because if each line represents one
NAND instruction, you have quite a bit
going on there.
[LAUGHS]
COLTON OGDEN: Yeah.
That would be interesting to
see, actually, because I'm not
too deep into that side of CS.
But I would like to study more of it.
I thought that--
NICK WONG: It is very theoretical, yeah.
COLTON OGDEN: Do you
ever watch Computerphile?
Have you watched their videos?
NICK WONG: I have not.
COLTON OGDEN: They have
really fascinating videos.
NICK WONG: That's awesome.
Are they a YouTube channel?
COLTON OGDEN: They're a YouTube channel.
NICK WONG: Sweet.
COLTON OGDEN: Let me see.
[? Brenda ?] was saying,
we have 35 new followers
since yesterday.
Yes.
Thank you very much--
NICK WONG: Wow.
That's awesome.
COLTON OGDEN: --everybody
who's following.
And I don't know if I told you, but
we have over 1,000 as of two days ago.
NICK WONG: Wow.
That's awesome.
COLTON OGDEN: Followers--
NICK WONG: Thank you, guys.
COLTON OGDEN: So thanks,
everybody, so much.
And also, thank you to the
people who just followed.
So Visicks-- thank you for following.
And [? RasKWK. ?] "Ras-quick"?
NICK WONG: Ras-quick.
That makes sense, yeah.
COLTON OGDEN: [? FY6-- ?]
these are some of the people
that followed a few hours ago,
but just want to shout them out--
[? TaznorKoran13421 ?] and
[? CodeBloodRexNanomizer, ?]
[? OoeyZuck, ?] [? FiveSharpPoint3, ?]
and [? OldForce ?] and [? LOL. ?] Thank
you very much for following.
NICK WONG: That's awesome.
[CHUCKLING]
COLTON OGDEN: So let me just make
sure that we're all caught up.
I think we're mostly caught up.
A lot of people are
excited-- lots of cool stuff.
NICK WONG: Lots of cool questions.
COLTON OGDEN: Oh.
So A golden emote is a custom--
[? GoldenKappa ?] is a
custom emote, I would say.
NICK WONG: That's sweet.
COLTON OGDEN: The real question is, can
you build a neural network in Scratch?
NICK WONG: I think someone has.
I would not be surprised if there
is a student from MIT who was like,
you know what?
I sat down and I built a
neural network in Scratch.
COLTON OGDEN: Because they are like--
yeah, because MIT-- you got to rep MIT.
You got to do something
crazy with Scratch.
NICK WONG: Yeah.
Yeah, exactly.
And MIT has this whole culture
of building cool things just
for the sake of building them.
I actually really enjoy their--
I really admire their
culture of doing that.
I think it's awesome.
We have a little bit of
a culture here of that,
but I think we gear more towards
the, can I get money out of it?
Nothing wrong with that.
But I think that I
admire the kind of just
develop for the sake of development.
I think it's very cool.
COLTON OGDEN: [? MoHalas, ?]
thank you very much for following.
And JP asked, is C a better language
to learn in the beginning than C++?
NICK WONG: So to ask if a language
is better to learn in the beginning
depends a lot about your context.
So if you have worked a
lot with Python and Java,
then it might make a lot more sense
to start the transition toward C++
because C++ has some of the tools and
object-oriented perks of a language
like Java or Python.
But it is much lower level
than either of those languages.
However, if you are
starting from nothing,
CS50 seems to think that C
is a great place to start.
And I agree.
And we'll actually
talk a little bit, when
we get into coding
some stuff, why I think
it's a great language to start with.
In particular, I think it helps you
think a lot more like a computer.
And that tends to be one of the problems
with becoming a computer scientist
or starting in CS, is, computers
have access to a lot of tools
that we don't as human beings.
And they think-- er--
think-- I guess until the singularity,
I'm going to not try and personify them
too much.
But they kind of process things in a way
that is very different from ourselves.
And it's important, as a computer
scientist, to realize that.
And even myself, having
studied for a couple of years,
I still find myself realizing new
ways in which computers process things
differently from me.
And that's very cool.
So I would argue that C
is a great place to start.
C++ also would work.
It does a lot of the same things.
But it depends where you're coming from.
COLTON OGDEN: And [? JPGuy ?]
says, thanks for clearing that up.
Let me just make sure.
I don't want us to spend too much time
before I actually start diving in.
People are saying they
recognize Computerphile.
Oh, and then [? UnsignedEd ?] wants
us to go into a bitwise operators.
NICK WONG: Excellent.
I'm really glad you asked
about that, because I
used to think that was one
of the most confusing things
that I thought people just
wrote just to be confusing.
When I started in CS,
I would look at code
and think that it was written to
be confusing for the sake of being
confusing.
However, that is not true.
There are often a lot of reasons
for why people make design choices.
And so we will talk
about, like, bitwise,
and why it might be really fast
or why it might be really useful.
It will deal a lot with
how we go into assembly.
COLTON OGDEN: Cool.
And then [? DyGween ?] says, hey, guys.
I'm a CS student from
Rio de Janeiro, Brazil.
NICK WONG: Oh.
Sweet.
COLTON OGDEN: So thank you very
much for joining-- appreciate that.
And it looks like they're
talking in Portuguese as well.
And [? DroveForce ?] says
hello from Mumbai, India.
NICK WONG: Wow.
That's awesome.
COLTON OGDEN: Worldwide representation
and [? BellaKeers ?] is joining us.
Hello, [? BellaKeers, ?]
thank you very much.
Why don't we dive into some of the
topics I want to take a look at?
So I'm going to switch over to
our handy-dandy computer view--
NICK WONG: Favorite screen saver.
[CHUCKLING]
I think as a tradition now, I'll
just open up with this every time.
I mean, I'm actually
going to be working--
thank you.
Or I guess the developers of
that should say thank you.
I'm going to be working in
a virtual machine because--
COLTON OGDEN: I was just about to
say, I don't recog-- this is Mac OS.
NICK WONG: Yeah.
This is not Mac OS.
This is Ubuntu, the desktop version.
And I'm going to work
in a virtual machine
because I like separating out my C
development from my actual computer.
And also, it's a little
bit more convenient.
There's a lot more
guides on how to download
C stuff onto a virtual machine.
I also happen to use this virtual
machine for my systems class,
so I have and do have a lot
of C tools on it already.
COLTON OGDEN: Nice.
NICK WONG: And it's super convenient.
So that's what we are currently
on, if you want to follow along.
COLTON OGDEN: There's a very
large, lovely prompt you have--
NICK WONG: Yes.
We have quite the prompt going on.
I was kind of playing around
with it right before the stream
because I realized that
my prompt was enormous.
It was so long because I like to have
a lot of information on my prompt.
But it's not super useful to you guys.
So I killed all that.
Now, you just have the current directory
and an equal sign-- greater than sign--
as my prompt.
COLTON OGDEN: And [? JPGuy's ?]
saying, that font's nice and big.
NICK WONG: Yes.
You guys should hopefully
be able to read that.
If it's too big, and we find that
it's making things inconvenient,
I can always shrink it.
But for now, hopefully this works.
[CHUCKLING]
All right.
So in C-- we'll talk about
make files in a little bit,
but otherwise, we're
actually going to start
with just raw compilation using CC.
And we're going to do
all sorts of cool things.
But the first thing we're going
to do is write our first C file.
So I'm going to use Nano as
my text editor of choice.
And we're going to say, you know what?
Let's make our--
I don't know.
We'll call it first dot C.
COLTON OGDEN: Do you use Nano
a lot for actual development,
or are you more of a Vim user?
NICK WONG: Not usually.
I tend to use, actually, Visual
Studio Code for actual dev.
But if I'm typing as I go, then
I tend to use Nano very quickly.
COLTON OGDEN: And then, do
you use VSCode in your Ubuntu?
NICK WONG: I do, actually.
So I have VSC.
I can do code dot, and that
will open that up for us.
And that helps me when I'm doing
any sort of integrated development.
And we might actually switch over
to that if we need to-- yeah.
Actually, this might be a good idea.
We're going to switch over to VSC, so I
can keep code open and what's going on.
So here we go.
We have a new prompt out here.
That might be a little bit too small.
We'll open things up a little bit.
Where is-- should be under View.
See, the problem is--
COLTON OGDEN: That's what
I would imagine, but yeah.
NICK WONG: Yeah.
I don't see it.
COLTON OGDEN: Everyone's going to
have their own settings, locations,
and whatnot.
NICK WONG: I know.
Everybody--
COLTON OGDEN: [? And JPGuy's ?]
saying no, use Visual Studio Code,
[? Kappa. ?]
NICK WONG: This is Visual Studio Code.
Oh, you're talking to [INAUDIBLE].
COLTON OGDEN: In Vim,
we have [? Vimer ?] now.
NICK WONG: Yes.
COLTON OGDEN: [? Vimer ?] kids,
if you're scared of Google,
then your best bet is Microsoft.
NICK WONG: Yeah, OK, I
could agree with that.
COLTON OGDEN: [? NonBored's ?]
saying they're a vi guy.
No!
Use Vim says JPGuy.
NICK WONG: I don't use Vim.
So Vim and vi are quite fast.
And if you want to be
well respected, I guess--
not well respected--
COLTON OGDEN: [LAUGHS]
NICK WONG: --but a lot of
coders will prioritize those.
COLTON OGDEN: Some of them do
get brownie points for Vim users.
This is definitely true.
NICK WONG: Which-- yeah.
Honestly it's deserved.
COLTON OGDEN: Whether it's
meritorious or not is up to debate.
I think the difference-- as long as
you're using a tool and doing work with
it--
NICK WONG: True.
As long as you're building things--
COLTON OGDEN: Everybody has preferences.
NICK WONG: It's true.
COLTON OGDEN: I'm a VSCode user myself.
NICK WONG: Yeah.
It's great.
Yeah.
We actually ended--
COLTON OGDEN: Were you using
VSCode before the games course?
NICK WONG: Yes.
I actually was.
COLTON OGDEN: How long
have you been using VSCode?
NICK WONG: I started using it, I think,
right after someone showed me Sublime.
Because I was--
[LAUGHTER]
I switched off of the CS50 ID.
And someone was like, oh.
You should use Sublime.
And then it kept asking
me for a subscription.
And I was like, well, this is dumb.
And I looked up for--
COLTON OGDEN: It's kind of irritating.
NICK WONG: --free IDE.
That's great.
And it was like, Atom and
VSC came up really high.
Someone suggested Emacs,
which is also super powerful.
A lot of my professors use it.
But I do not.
COLTON OGDEN: People in the closure
community are in love with Emacs.
NICK WONG: Yeah.
I think it integrates really
well with a lot of things.
COLTON OGDEN: It was
written in Lisp, which is--
NICK WONG: Which would make sense.
[CHUCKLING]
COLTON OGDEN: Closure people
probably like it a lot.
Anyway--
NICK WONG: Yeah.
That would explain a lot.
[CHUCKLING]
COLTON OGDEN: We're
getting off on a tangent.
I apologize.
NICK WONG: No.
It's all good.
I think that's one of the
best parts of these streams.
So we have our first C program,
and it ends in the dot C extension,
although, technically, you could
end it whatever extension you want.
And we're going to do is the
characteristic int main void--
oh, man.
Boom.
And this is technically a C program.
This, actually, will compile just fine.
Keyboard shortcuts are a pain.
So technically, I can compile this
into first, and I'll use first dot C.
And that compiles just fine.
I can even run it.
That's totally reasonable.
It does absolutely nothing--
COLTON OGDEN: This will still
be sort of covered in CS50.
It's just going to be using a compiler--
NICK WONG: Basic C.
COLTON OGDEN: --C code into
object code-- dash o-- yeah.
NICK WONG: Oh, right.
And we do actually cover
quite a bit in CS50.
I don't even know if we're going
to touch too much on objects.
We might touch on, libraries and things.
COLTON OGDEN: Oh.
That's true.
NICK WONG: I'll focus a little bit
more on data representation and things
like that.
But yeah.
So this is technically a C program.
It does literally nothing.
But-- just kind of as a reminder
to everyone-- this int main void--
well, int main is a very important
part of C programs, in the sense
that you need it in order to run.
That's going to be the
main thread, for example.
So I'm going to import some libraries.
Losing my mind-- for
example, standard IO
is, I think, a fantastic library to use.
And we're going to talk
about it quite a bit.
And what we can do is, we can also
accept command line arguments.
So we're going to allow for that.
And we'll do [INAUDIBLE].
Whoops.
I hate doing that.
That's a command shortcut
from Mac, but I always
forget that it doesn't work on this.
And now we have access
to all of these things.
If there is like a
variable that you pass in,
and you don't want to really use it
yet, and you want to start for later,
casting to void is a
non-trivial operation
but it allows us to ignore
this unused variable warning
that I will point out in a second.
Oh.
Well, OK.
There should be a warning if
I was using compiler warnings.
I think dash w--
unused-- I can't spell--
unused variable.
That might not be correct.
Whoops.
Oh, well.
You can pass all sorts
of flags to the compiler.
There's hundreds.
I don't know all of them
off the top of my head.
And I don't really use a lot
of them off the top of my head.
I just use whatever standards
are set by the class I'm in.
But they are good to know.
And we're not going to really
play around too much with them.
But if you have unused
variable warnings,
you can always cast
avoid to ignore them.
That's generally a development
practice rather than a production one,
but something that is, I
guess, good to be aware of.
So this program that we're going
to run at the beginning is--
let's say that we want to--
I guess we're just going
to hop right into it.
I want to be able to
filter Python files.
I'm really annoyed at my developers
for writing thousands and thousands
of lines of comments.
And I want to filter out
all of their comments.
So what I'm going to do is, I'm going
to allow us to open up a Python file.
And then I'm going to just
filter out those lines.
And shouldn't be too bad.
All I have to really do is
include our standard-- actually,
I think standard IO should suffice.
So what I'm going to do is--
we'll just take that
first argument from argv.
And we will open it
as a file descriptor.
So file star-- in file--
is equivalent to fopen of argv1.
And we are going to add in fclose--
actually, I think it's just--
oh. fclose works-- infile at the end.
And what this allows us to
do is read from that file.
So all I'm going to do is read out the
first, we'll say, 8 bytes of that file.
So fprintf to standard out-- oops--
of the first - bytes of that file.
And this is a reasonable way to do it.
And you might go, what's buff?
And I will then tell you, yes.
Of course.
Great question.
Buff is an eight-byte-long
array of chars.
And what I'm going to do is throw in--
COLTON OGDEN: Buff's short for
buffer, using it as a buffer.
NICK WONG: Yes.
We're going to use it as a buffer to
store whatever we want to deal with.
And then I'm going to open--
let's see.
We already opened the file.
And then what I can do is read in--
man, I can't remember the name of this.
Ah, read, right.
[CHUCKLING] Correct.
And read, I believe,
is source destination.
Let me just check that.
COLTON OGDEN: It's curious about
functions in the C programming
language.
NICK WONG: Yes.
COLTON OGDEN: [? Man ?] were
[? the Man ?] I guess, program.
[INAUDIBLE] looked them up.
NICK WONG: Yes. [? Man ?]
is a fantastic program.
It allows you to do
quick checks like that
if you forget which order things
are as far as arguments go.
And this should be totally fine.
COLTON OGDEN: Famous last words.
NICK WONG: Yeah.
That's never true.
But in concept, it's the right idea.
So we've now compiled first.
And now, if I run
first, this will break--
well, I guess not break, but we're
not going to really do anything.
And that's strange.
Because I didn't pass in a file, but
I'm also not checking for things.
And if you took CS50 or if
you were following along,
then you would know
that we actually usually
required that you check to make sure
that this sort of thing doesn't happen.
Accessing argv 1 without
actually necessarily having one
can be kind of weird, and
undefined, and freaky.
So we're going to do is--
if argc is not equal to 2--
one for the file name and one for the
actual name of the command being run--
then we're going to
fprintf to standard error.
And we're going to say
usage is %s filemame.
New line.
COLTON OGDEN: And for people unfamiliar,
argc is the number of arguments
that you passed--
NICK WONG: Correct.
COLTON OGDEN: --at your program
that you wrote at the prompt
when you executed your program.
And argv is an array of strings that
represent those individual arguments.
[? OPLAD11874, ?] thank
you so much for following.
NICK WONG: Where is that file?
I think it's actually just from file IO.
[INTERPOSING VOICES]
That's the other thing.
It's the read function.
I always forget where
those all come from.
I feel like file dot h is maybe
not right, but maybe it is.
Who knows?
We'll find out in a second.
No, that's wrong.
COLTON OGDEN: Well, because, didn't
it compile when you had it written.
NICK WONG: It did, but
it was just being dumb.
It's because I'm not
passing a lot of the same--
with unused variable-- with specific
warnings-- flags to the compiler.
And so that's where we're
going to use Google--
where I don't want to include POSIX.
I want to include--
COLTON OGDEN: Oh, no.
We're back in Mac OS X.
NICK WONG: File operators.
Yeah.
This is Mac OS--
C library.
A lot of times, these sorts of
things, I just forget what they are.
Oh-- standard IO, I think, is--
oh.
I thought that's what that was.
I thought read was part of standard IO.
In fact, I'm fairly certain it is.
COLTON OGDEN: And this
is a common lesson, too.
You don't need to memorize
all of the functions--
NICK WONG: Right.
Exactly.
COLTON OGDEN: --that exist in C. The
important thing is that you understand
the syntax and how to solve problems.
And then you can always--
modern developers have the luxury
of just being able to Google--
and also, modern developers are building
larger, arguably more complicated
systems than they were
in the 80s and 90s.
Maybe not--
NICK WONG: Right.
Exactly.
COLTON OGDEN: It depends
on how you define that.
But I think-- definitely using a lot
more libraries and having to memorize
a lot more functions--
NICK WONG: Right.
COLTON OGDEN: --I think is
probably, definitely the case.
So give and take.
We have Google, but we also have
millions of functions and libraries
to sort through.
And it's impossible to
remember all of them.
NICK WONG: Right.
COLTON OGDEN: Like never--
NICK WONG: I mean--
COLTON OGDEN: Even the ones
you use on a daily basis,
like, what arguments go into
this function in what order?
Doesn't matter as long as you
know what the function does
and how to use it to
solve a problem, right?
NICK WONG: Right.
Exactly.
So let's see if we can figure
out what's going on here.
Actually, I can switch to fread and
have that be from standard library.
That would be fine.
COLTON OGDEN: That's what
[? RasKWK ?] just said, too.
NICK WONG: Oh.
Nice.
COLTON OGDEN: Fread from [INAUDIBLE].
NICK WONG: We agree, which is good.
COLTON OGDEN: It's like ESP.
NICK WONG: Oh-- or not.
What does fread require?
This is where things are kind of fun.
I can use that from standard IO.
Oh.
I see.
So what they have you do--
sure.
OK.
That's fine.
So we'll use fread from standard IO.
And what we will do is have that the
reading into the buffer from here--
eight bytes of size--
or, sorry-- size 1--
8 bytes.
And we'll have that read from in file.
And that should be fine for us.
Fopen is also too few arguments.
Right.
That is a great point and
I totally neglected it.
We're opening things up for reading.
I don't remember if it takes a standard.
COLTON OGDEN: I see you're
used to using single quotes.
NICK WONG: Yes.
[CHUCKLING]
COLTON OGDEN: Python or
Javascript developer.
NICK WONG: Single characters-- and I
think it requires a constant char star.
So that would be really bad.
And now we should be OK
on each of those things.
And we get a segfault. And so
basically, what's going on here
is, you might go, well, I shouldn't have
gotten a segfault. I caught the error.
And then you'll see in the same
place where this is what's going on--
where we actually should have exited
with some error code and then moved on,
right?
I keep forgetting which
language I'm writing in
as well as where I'm writing things in.
Oh, and is from standard library.
There we go.
Now we're all on the same page.
A lot of these things
I don't necessarily
memorize for the same reasons
that Colton pointed out.
If we were writing in a language that I
need to write in consistently for work,
then I would naturally
memorize most of these things.
But otherwise, I'm not
going to generally.
COLTON OGDEN: There's only so
much finite short-term memory.
NICK WONG: Right.
Exactly.
And so if we were writing
in Python, no problem.
I can deal with that,
basically, at any time.
But if we are actually
writing in C, then I
think it's just fun to play
around and see what's going on.
So we now have a functional
program, we think.
But if we were going
to go through here, it
would be a decent idea to
check that fopen didn't fail.
And generally, whenever you're
doing these syscalls and things that
are going on, then I would actually
be very careful about making sure
that a syscall didn't fail.
So for example, if fopen fails,
we might go into man fopen
and see what ends up happening.
Sorry.
My screen is a little large.
But if you go down to the return--
man pages have a pretty standard
format, so you can actually
usually guess where things go.
And we get that return value.
So upon successful completion,
it returns a file pointer--
yeah.
Not a file descriptor
but a file pointer.
Otherwise, null is returned, and
errno is set to indicate the error.
So what we can do is, then, we
can say, if not in file then
I want to fprintf to standard error--
some sort of error number.
Or we'll say, error blobdeblah,
and file not found maybe.
And then there's actually something
really cool you can do there.
But we will talk about that in a second.
Errno, and then we're going to exit.
And this might be with
a separate error--
or I'm going to actually
just pass errno.
Errno should be set, but
we'll find out in a second.
Oops.
Compile that-- of course,
where is errno to click?
There are so many ways in
which I don't like that.
We'll deal with this later, then--
file could not be opened.
And we'll just set error to 2.
And then what we can
do here is compile it.
And now, if I tried to open
a file that doesn't exist,
the file couldn't be
opened, which is good.
So let's see-- I read in the
chat, [? TheDuckThough ?] says,
don't do exit, kids.
It will not run any deallocation
and leak a lot of memory.
Well, that would be a good point.
I don't know of any,
necessarily, accurate functions
that do automatic deallocation
and non-leaking of memory.
If you're working in
a low-level language,
you should make sure to
do your own deallocations
and non-leakages of memory.
In this case, it would
be impossible for me
to have a leakage of memory in the
sense that I never allocated any--
at least, I didn't manually
allocate anything to the heap.
So it's not a problem here.
There is-- if you notice
at the very beginning,
I went with underscore exit, which
doesn't do any of its own cleanup.
And the reasoning for
that basically being
that generally, when I'm
coding in a low-level language,
I'm expected to do my own cleanup
manually because for courses, they
don't want you just using
library functions that
can help clean everything up as you go.
So that is what the purpose
of that function is.
And so it's generally a good idea
to be very aware of what exactly
is going on when you call
any one of these functions.
So we're going to talk
about that a little bit.
We're going to use strace
as well to talk about where
actual system calls are going.
But this start up process is
always a pain for me, regardless
of when I actually first start writing.
And I don't usually write C files
completely from scratch like this.
I generally actually pull template
code that I just store somewhere.
So I'm not actually used to
this format for doing things.
We're actually going to include errno.
I forgot that it is a library.
And there's a really cool function
that I can't remember the name of.
And let me see if I
can find it because--
and this might seem a little bit
ridiculous-- but the reasoning for that
is that it allows you to
describe an error using a string.
And I don't remember what
that function is called.
So we're going to Google that
because welcome to development.
Errno-- string description.
COLTON OGDEN: [? C9221, ?]
thank you for following.
NICK WONG: Strerror-- that
might be what I was looking for.
Well.
OK.
That might be true.
We'll try that.
So this is part of C++, as far as
this goes, but it might be part of it.
We'll find out.
Let's go see.
So these are all kind of like
non-, I guess, important--
what was that called?
Strerror.
I feel like that exists.
Nope, that's not a library.
That's probably an errno.
Hopefully it is.
If not, I won't spend
too much time on it.
But it is kind of a cool thing
that you have access to and don't
have to really deal with on your own.
Ah.
There we go.
Sure.
Oh, no.
That's not what I want.
You are-- Does it type int?
Really?
All right.
Well, then, we're not going
to spend too much time on it.
There is a function
that exists like that,
and I apologize for not
knowing off the top of my head.
It's there somewhere.
That's OK.
So-- oh.
That was not what I wanted.
There we go.
So now I run this.
It tells me which error I got.
And then we're all good from there.
COLTON OGDEN: Error 2--
NICK WONG: Yes.
Error 2, which is what it was
set to anyway, but whatever.
So now, ignoring that part, I'm
going to answer some of the questions
that I see upstairs--
or not upstairs.
COLTON OGDEN: Upstairs?
NICK WONG: In front of me--
COLTON OGDEN: I've gone back--
NICK WONG: There's
quite a few questions.
COLTON OGDEN: So [? ThePeeingHorse, ?]
which is an excellent name--
[LAUGHTER]
--says, people learn the C
language when there's GO?
That blows my mind.
What are your thoughts on that?
NICK WONG: So it's interesting,
because in the C language,
you are actually kind
of stuck to this whole--
you get a specific stock allocation.
You can't modify that allocation.
You can't take some thread stack
and move it to somewhere else.
In C, you are stuck with
whatever stack you're
given, because the actual stability
of pointers matters a lot.
However, in GO, that's not true.
You can move things around.
It's a garbage-collected language,
and there's a bunch of stuff
that I don't understand
about how that works.
And you can move that sort of
thing around however you'd like.
And that's really cool, but I think that
starting with C is extremely useful.
And technically speaking, if
you're talking about which language
you want to pick,
people will always have
their own opinions on where you
should start and things like that.
My opinion is that starting with
something like C is totally reasonable.
It teaches you how to
think like a computer.
It puts you in charge of all of your
own memory allocation and it allows you
very low-level access to a computer--
which, I think, if you
accomplish all those things,
it's a widely-used language.
There's well-developed support for it.
And there's a community that
knows exactly what they're
talking about that has been
around for, literally, decades.
And so I think that
all of those attributes
make it a really desirable language
for learning at the beginning.
I also would argue that learning a
specific language doesn't necessarily
matter, in the sense that, as long
as you're starting to think like
a computer, and as long as you're
starting to actually think of things
algorithmically, and efficiency-wise,
and as thoroughly as you possibly can,
then you are developing the
mind of a thought process--
not of a thought process--
of a computer scientist--
COLTON OGDEN: That's kind of meta.
NICK WONG: --and that
thought process there-- yeah.
You're developing the thought
process of a thought process--
You're developing the mind
of a computer scientist.
And I think that that's
what's important.
COLTON OGDEN: Yeah.
And there's also no reason that
they're mutually exclusive.
You can learn GO and C. And maybe even--
NICK WONG: Right.
Right.
Just use them at the same time.
COLTON OGDEN: And I'm sure that GO
was actually implemented on top of C,
or at least, well--
NICK WONG: I don't know.
Yeah.
I don't actually know--
COLTON OGDEN: It could be.
I mean--
NICK WONG: It might
have its own compiler.
Yeah.
COLTON OGDEN: It could
have its own compiler.
But yeah.
I think that religious arguments
with languages I don't think
is super productive.
People can learn multiple--
NICK WONG: Can learn
all sorts of things.
[CHUCKLING]
COLTON OGDEN: It's good to
learn multiple programming
languages-- different ways of thinking.
NICK WONG: Yeah.
Exactly.
COLTON OGDEN: People had some
cybersecurity comments as well.
Brenda was joking, you don't
follow the CS50 style guide.
NICK WONG: Right.
I believe the CS50 style guide
actually does something that I hate--
very strongly dislike--
which is, they do this--
which I detest.
However, as a TF-- as someone grading
things and reading through code--
I love that because it is
so much easier to read.
However, I used to love it.
I now don't really, particularly
care, and I think this looks cleaner.
I think that having this on its own
line is just kind of strange to me.
So I generally prefer this style.
COLTON OGDEN: This is the
original Kernighan and Ritchie--
NICK WONG: Right.
[CHUCKLING]
COLTON OGDEN: --style,
mostly because, at the time,
they only could fit like 10
lines of code onto the screen.
But a language that I've been
diving into recently is C#.
And in the C# community,
you are expected to do the--
NICK WONG: This one?
COLTON OGDEN: Yeah.
And if you're writing
in people's code, there
are certain standards and
expectations in the community.
NICK WONG: Right.
Right.
COLTON OGDEN: And if you don't follow
those, you're kind of an outlier.
NICK WONG: You get kind of
pushed in your [INAUDIBLE]..
COLTON OGDEN: It's the
same thing in Python
how I used to get scolded for using
Caml case notation for variable names.
NICK WONG: Right.
Yeah.
No.
That's terrible.
But if you're coming from
Swift or Objective C--
COLTON OGDEN: Yeah.
People were very upset about that.
Also shout out to--
David's in the chat.
[? DavidJ.Newlon. ?] Tabs
or spaces, Nick, says David.
NICK WONG: Tabs or spaces?
I would thoroughly argue, spaces--
portability and making sure
the Python stops yelling at me.
COLTON OGDEN: Yeah I mean, modern text
editors just let you say implement--
NICK WONG: Yeah.
Actually, I was going to point out--
if you look down in the bottom
right where I am currently sitting--
we'll see if I can hop out of there--
where my mouse is and where I was--
spaces is set to 4.
So all of my tabs actually are spaces.
I hit tab out of convenience, but
generally I try to be very consistent
and use spaces only.
COLTON OGDEN: Yeah.
I would hate having to type four
spaces every time, every line--
or eight spaces or 12 spaces--
NICK WONG: Right.
Exactly.
It's a huge pain.
COLTON OGDEN: Tabs that are implemented
as spaces are definitely the way to go.
NICK WONG: I'm a huge fan of that.
COLTON OGDEN: Let me make sure we didn't
miss any other key comments up above.
[? JPGuy's ?] saying
they don't develop in C,
even though they been
a lot of time here.
I mean, we don't really spend a
lot of time doing C on the stream.
I mean, obviously, C--
NICK WONG: No, no.
COLTON OGDEN: [? It's 50/50 ?] C,
but as kind of a learning point,
and they've sort of let you jump
off into Python, JavaScript,
other languages that are
actually more in vogue, I think,
for most developers these days.
Aqualad11874, thanks for streaming.
Thanks so much,
[? Aqualad, ?] for joining us,
and thank you for the follow earlier.
People were helping you debug live.
[? UniSTD.H-- ?]
NICK WONG: I always appreciate it.
COLTON OGDEN:
[? --was Brenda ?] said it.
I'm not sure what that might
have been a reference to.
NICK WONG: There's all sorts
of cool libraries for things.
I tend to stick to very
simple, very minimal libraries.
Well, I say minimal,
standard libraries is huge.
What I basically mean by
that is I stick to things
that are as simple as I can find
them, or as close or low level
as I can find them.
And generally, the
reason for that is that I
wants to be very consistent
in how I actually end up
developing an any piece of C code.
I also try not to include
libraries if I don't have to.
And people would argue that
there's like, efficiency
purposes to that and things like that.
That's true, you know, with a caveat.
But it's more important to me as a coder
that I don't include a bunch of fluff
everywhere that people
don't need to read through,
or that makes it harder for you
to process where things came from.
And for debugging purposes, if I
include, like, 10 different libraries,
I might not necessarily know
where any one function came from,
and it's easier for me to just
keep in my mind what's going on.
And especially since
you guys are getting
kind of a live version
of how coding works here,
you basically are seeing a little bit
of how my development process works.
Which is very-- tends to be very--
COLTON OGDEN: Very Google-oriented.
NICK WONG: It's also being
very Google-oriented.
And I saw someone asked--
what was the question-- oh.
Someone asked which
programming language--
or did I learn a single programming
language for technical interviews?
And the answer is I actually learned
programming languages because I
thought building things was cool.
My focus at the very
beginning, I don't even
know what a technical interview was.
I had no clue.
I just knew you somehow could end
up working at big tech companies
or whatever that was.
But I just thought was really cool, I
like building tools for varying things.
And so I kind of accidentally
learned a lot of languages.
I learned a lot of them through my
classes, I learned a lot of them
just by like wanting
to build x and knowing
that I needed to hop through
learning this language to get there.
But the language itself
was usually not my goal.
I actually don't have a single
language yet that I've learned
for the sake of learning that language.
However, I think this winter
break that might change.
COLTON OGDEN: Which language are you--
NICK WONG: I think I
might actually learn
Go, for the specific reason of thinking
that it's a very cool language.
COLTON OGDEN: It's apt because you
going to work at Google, so I mean--
NICK WONG: Right, I think
that would make sense.
And so I think that that is--
that's probably something
that'll change a little bit.
But in general, that's still
going to be very project-oriented.
I think that it's a little bit
easier to motivate yourself
if you have project-oriented
things going on in your mind.
And also, something that's
interesting about technical interviews
is a lot of companies
that I've interview at,
I haven't really needed to
code in a specific language.
With startups that's a little different.
But with big tech companies--
COLTON OGDEN: Startups have
more of a specific stack
that they're looking to--
NICK WONG: Right, exactly, they're
like, I want people who can do this,
because that's what our team
is currently working on.
COLTON OGDEN: It's fairly
small, it's fairly focused.
It's not as wide-reaching as like--
Google obviously has a
million different things.
NICK WONG: Right, you
can go develop with.
Anything and so I think generally
speaking, I will learn kind of--
I mean, I learn languages because you
do need them to write actual code.
You can't write in pseudocode.
Well, Python, basically.
But you can't otherwise do that.
COLTON OGDEN: Yeah.
NICK WONG: But I love Python,
I use it all the time.
COLTON OGDEN: Python's a great one.
NICK WONG: It's great.
COLTON OGDEN: I love Python.
NICK WONG: But I generally, in
a lot of technical interviews,
I kind of write in a blend of languages.
There's certain things that
are really convenient in C,
so I might talk about them,
and there's certain things
that are really convenient in
Python, so I might kind of like
ping something towards Python.
The funny thing is like, if you look
at my like whiteboard interviews,
I'm pretty sure I
like, every other line,
have a semicolon at the
end of the line, and like--
[INTERPOSING VOICES]
Yeah, it's like, I don't know
where that language came from.
That's from C, C++, and Java.
And so it's very interesting.
Oh, someone also-- while we're on
the topic of technical interviews--
asked, can you look at these
libraries during your technical coding
interviews?
No, not usually, at least
not in in-person interviews.
And I would also recommend
not really doing that.
You don't really need
to, because I think
that you can-- an interview I
had, I said, well, you know,
there's a library that does this.
I know it exists.
I don't know the exact syntax, but
I'm going to write it like I do,
and you'll understand what I mean.
I'll use clear syntax
and clear things in order
to indicate to you, my
interviewer, what I'm trying to do,
because the interesting part
is solving this problem.
That's what I'm after, that's
what you're after, and you know,
you have four interviews today.
Hopefully, this will be interesting.
Because I want to solve the problem.
I don't need to focus on, is it a
library that's capitalized or not?
Who cares?
I can go Google that.
And so generally what I
would do there is I'll say,
if you don't-- and
it's called a library.
You know, let's say I forgot Malok,
which that might be kind of a red flag,
but like, we'll pretend that's not.
And I say, we're just going to call it
the Allocator library, and I'll say,
here's the syntax for it and concept.
It has some sort of allocate,
it as some sort of reallocate,
and it has some sort of delete.
And so that's kind of a weird
mixture as far as syntax goes,
like a purist would say,
well you're blending C, C++,
and like some weird version of Python.
I mean, that's fine.
I'm still hitting the concepts.
I'm showing and demonstrating
that I understand, what does it
mean to allocate it on the heap?
Things like that, I
think, are really useful.
I think those concepts are
much more useful than actually
memorizing all of those things.
[? TwitchHelloWorld ?] says
that that's interesting.
I have to be super exact and technical
in interviews in my area, though.
Only for teaching
interviews do I get asked
to actually do something
similar to a coding interview.
Yeah, my pleasure.
Oh, they said thanks, and I said yes.
COLTON OGDEN: [? HongYi ?] and
[? ImagineAWave, ?] thank you very much
for following us.
NICK WONG: Yeah, awesome.
COLTON OGDEN: Let me just see.
We have a lot of people--
[? AraniAndAndre, ?] I
noticed during the chat.
[? TheDuckThough, ?] I think we
saw [? TheDuchThough ?] earlier.
Do you still use the auto and
register keywords for C50?
I'm not sure if--
oh, well, that's for C++, newer C++.
NICK WONG: Oh, yes.
COLTON OGDEN: [? FCtrl.H. ?]
[? CRonics ?] made a point.
I'm not entirely sure
what library that is.
NICK WONG: Yeah.
COLTON OGDEN: "Using
libraries is for the weak."
NICK WONG: And I think we kind of
hit on something similar in the last,
maybe two streams ago,
where it was like.
If I built everything
myself, would I be secure?
And I'd argue, no.
And so I mean, that's
kind of interesting.
But yes, using libraries
is for the weak.
I count myself amongst the weak.
I also sleep, which is for the weak.
COLTON OGDEN: Why exit
instead of return?
NICK WONG: Right.
Basically, that just comes
from a old habit of mine,
where I am actually in the
process of completing a bunch
psets where we were dealing with
process forking and threading.
And so I was using
exit from those psets,
and I just kind of got into that habit.
There's not necessarily a huge
distinction in this particular case,
because we have a single thread,
we have only the main thread,
and exiting from it as
well as returning from it
achieved roughly the same goal in
that they both end the function.
A return, it's going to return whatever
that number integer you have out to,
I guess, the kind of error return here.
This.
And it'll deal with a lot of just
kind of what process cleanup has.
I like exit.
It does do some of its own cleanup.
It deals with a little bit
of marking a process as dead
and getting it killed
and things like that.
But in this case, I don't think it
actually really matters too much,
and for our purposes it
certainly does not matter.
COLTON OGDEN: All right, cool, cool.
Let me just make sure-- we
have, oh, there is so much chat.
NICK WONG: Yeah, we really appreciate
you guys for participating.
COLTON OGDEN: It's amazing.
We're super happy.
I feel horrible that we
haven't been able to read off
every message at this point.
And [? Eddie was ?] saying, C++ isn't
[INAUDIBLE] either, which is correct.
[? Fatma, ?] hello,
thank you for joining.
"Hey, [INAUDIBLE],, what
are the benefits of using
float instead of double, which
calls for higher precision.
Just the memory usage?"
Asks [? PresidentofMars. ?]
NICK WONG: So there can
be a bunch of reasons
for using a float instead
of a double, or vise versa.
Generally speaking, I
will argue for using
as little memory as possible
and as simple as possible.
So if you're talking
about some sort of float,
then we're dealing with a
fairly large amount of memory
relative to an int or a char.
If you're talking about a double,
then you're similarly in a boat
where you're using quite a bit of
memory relative to an int or a char.
And I actually generally don't
really use float or double--
I mean, that's a weird statement.
COLTON OGDEN: [INAUDIBLE].
NICK WONG: Yeah.
It's a weird thing to say.
COLTON OGDEN: Integers all the way.
NICK WONG: Just all integers.
And I think that there
are, I guess, just use
cases in which either one is useful.
Sometimes it deals a little bit more
with which platform you're on, but even
then, in the modern day and
age, that's not really true.
I can't think of any use case right now.
If I think of one when I get
there, I will let you know.
I think it's a good question
that broadens to kind of,
why do any one practice over others?
So for example, why would I stick
to using integers and chars?
Integers don't cover enough numbers,
and chars are only one byte.
But, for example, we're going to
talk about how one of the powers of C
and low-level languages in general,
is I get direct access to memory,
and I can think of it as
kind of like a raw block.
It doesn't have any shape,
it doesn't have anything
that it really does on its own, and
I can reshape that block however
I'd like, which can be really useful.
So that can be really interesting
to do, and we'll get there
in probably a couple of seconds.
Well, a couple minutes.
COLTON OGDEN: Thank you very much,
[? DwayneYasir ?] for joining us.
I know that--
I don't know which environment
I saw it in recently,
but depending on whether you
have a 64 or 34-bit processor,
doubles are actually more
efficient than floats,
because they're typically 64 bits.
NICK WONG: OK, I can see that.
COLTON OGDEN: So they're the--
[INTERPOSING VOICES]
NICK WONG: OK, I can see that.
COLTON OGDEN: So it can
be loaded in one CPU call.
And I forget whether it was in--
I think it applies both to the content
of C, C++, and also the VM platforms,
like the CLR and Java, JVM.
They're able to just
more-- especially if you're
doing a lot of double
operations in a tight loop.
NICK WONG: Right.
COLTON OGDEN: Loading that double into--
NICK WONG: Can be very annoying, yeah.
COLTON OGDEN: That's the only context
that I'm aware of, besides the fact
that you get more precision in with
a double, where you can actually
get performance costs out of it.
But to your point, I don't think
for a lot of use cases, that's
going to necessarily matter.
I think it's really for really intense
stuff, like game engines, for example.
NICK WONG: Right.
Which does come up a lot.
COLTON OGDEN: Yeah.
NICK WONG: Game developers have to
deal with a lot of things like that.
It actually matters.
All right, cool.
"C has not a garbage collector."
You're right, C does not
have a garbage collector.
C has very little, actually.
COLTON OGDEN: Yeah, C is a
very lightweight program.
NICK WONG: It's pretty limited.
COLTON OGDEN: Well, amazing
libraries that people--
NICK WONG: Exactly.
COLTON OGDEN: Does Newt compute from
one religious debate to another?
That's been sort of the theme today.
Everybody was shutting out David.
David asked about the tabs question.
NICK WONG: Yeah.
COLTON OGDEN: Pascal Case says,
code editor, feels good man.
NICK WONG: Cool.
COLTON OGDEN: It's great in C+,
but you go to Python, and people--
NICK WONG: Yeah, people--
[INTERPOSING VOICES]
COLTON OGDEN: Instant vomit.
NICK WONG: Yeah, they
just can't deal with it.
I can barely deal with it.
I think in my C programs,
I write in underscores.
COLTON OGDEN:
[? TheDuckThough ?] says, ew, C#.
I actually like-- if you're
comparing it to Java,
I actually like C# quite a bit.
NICK WONG: Yeah, I'd agree with that.
COLTON OGDEN: I tend to prefer
coding in Python over C#.
C#, I actually enjoy.
I use it in Unity development.
It's actually a pretty nice language.
It's got a lot of cool features.
And they're consistently adding
new stuff to it every other year,
which is great.
NICK WONG: Yeah, that's true.
COLTON OGDEN: Tabs are
converted to spaces,
aren't they, asks [? Bhavic Knight ?]
In the context of text editors, yes.
NICK WONG: Yeah, they can be.
You have to be careful about that.
Python will catch you on it if
you're switching through things.
I'm sure a bunch of other languages,
interpreters, will catch you on that.
COLTON OGDEN: Yeah.
If you you're doing just raw, like
a raw text editor or something,
and you're using tabs versus spaces,
it's not going to know the difference.
It's going to know the difference.
NICK WONG: Right.
They'll pick up on that.
COLTON OGDEN: OK.
Thank you all, from the low level
programmers, says [? HeenaLar. ?]
Thank you very much for joining.
People want to fight religious debates.
NICK WONG: Yeah, every time you
bring up like this sort of thing,
once you get into like C or C++, or
actually any programming language,
I guess, people will always have their
own opinions on like what libraries you
should use or shouldn't use.
I'm generally pretty lax about that.
The times that I would not be are
when they affect memory or efficiency,
or they have some known
bug that I'm aware of.
But otherwise, if it gets
the job done and it does not
violate any immediate practice that
I know of, then I see no problem.
COLTON OGDEN: Enough boring
C. Let's do inline assembly.
NICK WONG: Inline assembly.
Yeah, I don't really
want to ride assembly.
COLTON OGDEN: That's some
90s programming right there.
NICK WONG: Yeah.
COLTON OGDEN: [? Nowanda353 ?]
asks Nick, what's
the best thing you've built so far?
NICK WONG: Oh, that is a great question.
I have built lots of cool things.
Sorry, that sounded very arrogant.
That was not intended that way.
I think I tend to detach myself
from the things that I build,
and just kind of look at
them as their own objects,
and think that they're kind of cool.
So I spent a lot of time developing
a auto grading software for a club
that I run here.
There's some labs that I've
built for a cybersecurity club
here that I think are very cool.
I built my own version of a VPN.
Originally, it was based
on open VPN, and then
I kind of modified that and tweaked it.
So I guess I would say I kind of like
stood on the shoulders of giants there,
but I thought that was really cool.
I built, or I guess I
leveraged a Raspberry Pi Zero,
it was very small, and built
or designed a device that
allows you to plug it into
a computer through USB,
and it can simulate basically any
kind of connection or hardware device
that you'd like.
So you can kind of pick through
the Raspberry Pi's interface, which
generates its own Wi-Fi
network when it has power,
and you can connect to it through,
I built an app for it on my phone,
or you can just connect to
it via the Wi-Fi interface.
What that lets you do is you can
pick what you would like to simulate,
so you can simulate like
an ethernet connection,
you can simulate a keyboard
connection or even a mouse connection
if you'd like.
And I found that the keyboard and the
ethernet interface are the most useful,
in that what I can do is then,
if I'm simulating a keyboard,
then I can actually brute
force like the password
to your computer, which is kind of cool.
I think that's awesome.
I would never use it.
I have no need to, but
I think that's awesome.
You know, I got to go, this is a
really cool thing to be able to do.
If you simulate an ethernet connection,
then what you can actually do
is, I guess, pretend that
this is now the internet.
You can set yourself as like the
highest priority ethernet connection,
and then your computer
will send out connections
because it's listening for and asking
for like site updates and things,
even when your computer
screen is locked,
so I can kind of bypass
your password in that way,
and maybe poison a
bunch of your browsers.
And then when you log back in,
they are all like messed up
and they will reach out to me instead
of where they're supposed to go.
COLTON OGDEN: White Hat
Hacking for the win.
NICK WONG: Right. [? AllWhiteHat, ?]
I actually do-- am very,
very solidly against
hacking for personal gain.
I think that that is awful.
So there's all sorts of, I
guess, ethical debates and qualms
that I have, or maybe not qualms.
I very thoroughly am against
people who hack for personal gain.
I think that that would be
awful, based on the sense that I
think hacking in computer science--
and in general, I have a pretty
positive view of humanity--
should all be used to help people
in general, and help the community,
help the world as a whole.
So.
COLTON OGDEN: It seems to be
the case that, I mean, just
by knowing how it works, you have
the best defense against that.
NICK WONG: Right.
Also true.
COLTON OGDEN: The thing that you hate
so much, you find a way to combat it,
I think.
NICK WONG: Exactly.
COLTON OGDEN: And they're saying shout
out for Google's future CEO, Nick.
NICK WONG: I appreciate it.
COLTON OGDEN: OK, we have
done a ton of comment reading.
We'll pause here.
I'll come back on the comment reading.
Let's go to the next, I
think, sort of C coding.
NICK WONG: Yeah, we'll keep going.
So we have now kind of checked
our file descriptors and things.
I guess we've checked we have
the right number of arguments.
We have checked that we have an
actual file that has been opened,
and then we set up a buffer.
We read into that buffer and we print
in the standard out for that buffer.
So one of the kind of cool
things that you can do--
oh, whoops.
Not what I wanted.
Make sure that that's up to date.
And then what I can do is
read in itself, actually.
And that broke, which is great.
I gave it three arguments
because I can't read.
And we get the first 8 bytes from our
own file, which is kind of interesting.
So what this allows us to do is, I can
set this, we might say like some int,
and it's actually a little bit more
general here, and we'll have N,
and we're copying in N bytes.
And what I can do is then
recompile this and run this,
and I get that, which
is kind of interesting.
COLTON OGDEN: Apologize also
that [? MissSchick ?] followed us
at the same time that
[? DuaneNeese ?] did,
so thank you very much for following.
NICK WONG: Awesome.
And so you get these kind
of like weird characters
that my terminal does not
interpret, and just kind of like
throws its hands up and gives up.
But generally, I have now been able to--
oh, whoops, that's not what I wanted.
I can copy up to 64 bytes
of my file, my input file.
And I can do that with any file, really.
I could even go to like my desktop.
And I don't know what's on
my desktop, but sure, we'll
do our like Bash history.
Oh, that's a bummer.
So it couldn't actually open
that file, which is a shame.
Oh, [? .bashhistory ?] is probably why.
There you go.
And so you get the
first 64 bytes of that.
So we're doing something very simple.
We're just opening a file,
reading out the first 64 bytes,
reading it into a
buffer, which might cause
people to think oh, this is terrible.
But that's OK.
We're going to kind of
ignore that problem for now.
But what we could do after we have
started to open files and everything
is, maybe we want to be able
to read in the whole file
and then print it out
in buffered chunks.
And that would be a very
reasonable thing to do.
So what we're going to do is while--
and you might notice there's
an unused value here.
Technically, what I
could have done is this,
and if I had better warning
setup, than I would have gotten
a warning on the fact that f.read
returns a value that I'm ignoring,
but we're going to kind
of ignore that for now
and pretend that it doesn't matter.
I don't know why I
started typing up here.
I'm losing my mind.
And so what we can do is while f.read
buff, 1 and N file is not equal to--
I believe it returns 0 in the file.
We'll find out.
Then what we can do is
print out that buffer.
And what this, in concept,
if I'm not losing my mind,
which we all know that's
not true, that should
allow us to read in the entire
file, and basically, first
is going to have a different name now.
We're going to call it Cat, and
./cat of first.c should read out--
pretty close.
We're reading out some junk.
We shouldn't necessarily be
doing it that way, but that's OK.
So this is roughly the right concept.
Oh, there's a bunch of those.
Oh, OK.
That kind of makes sense.
Does that make sense?
Let me think about that for a second.
This shouldn't
necessarily be junk there.
COLTON OGDEN: Have you
got those semicolons?
Are those semicolons?
NICK WONG: It looks like they are all--
I don't know.
Let's see if we can figure
out what those characters are.
COLTON OGDEN: Oh, no,
they're not semicolons,
because there's a
semicolon there in that.
NICK WONG: Yeah.
There's kind of an interesting
character going on there.
COLTON OGDEN: I think
you've been hacked.
NICK WONG: Yeah, I've
been hacked by magic.
COLTON OGDEN: Clang.
NICK WONG: Yeah, that's
an interesting character.
My guess is that that deals with
junk that is not the null terminator,
would be my guess, but
we'll find out, maybe never.
But that does roughly cat our file out.
I also know that this terminal has some
bugginess, where if I type underscores,
they don't always show up.
Like I can I think echo,
underscore, underscore.
Oh, just kidding.
OK, so you know.
COLTON OGDEN: Does
your normal shell work?
Not the integrated one in VS code, but
the one that's in your actual terminal.
NICK WONG: We can find out.
Let's see.
That is a great question.
Oh, well, you get that.
Let's see.
Where is everything?
./cat first.c.
Oh no, it's even weirder.
COLTON OGDEN: OK, fascinating.
NICK WONG: Interesting.
My guess is that there is some
junk sitting in the buffer
and I'm not clearing it.
I don't actually zero the buffer.
And so that might be
something to look at,
is like what happens if we fprintf--
whoops.
I love that we always-- this is
like the perpetual sidetrack.
COLTON OGDEN: It's a good line.
NICK WONG: Yeah, it's like a very
cool, I think, thing to be able to do.
This actually should-- well, no.
It won't [? segfault. ?] That is OK.
It's OK to type.
Now, if I do first--
actually, let me also--
.txt.
COLTON OGDEN: I was about
to say, do you want to like
write a test script for it.
NICK WONG: Yeah.
And then we can run this, test.txt.
And OK, cool.
It ends up actually being
OK as far as that goes.
My guess is that at the end,
we are encountering stuff
where it's not reading exactly.
Because our buffer is 64, so
let's say I read in 1024 bytes.
COLTON OGDEN: Oh, if it reads more
than the number of bytes that are
in the file-- it's
going to try to read--
NICK WONG: Yeah, my guess is
it's doing something weird.
COLTON OGDEN: Because there's not
64 characters in that text file.
NICK WONG: Right, exactly.
So it's doing something kind of strange.
COLTON OGDEN: It's just reading.
NICK WONG: Sure, that's fine.
And so if I was smart and if I wanted
to actually like thoroughly debug this,
then what I would say
is, we should be very
careful about making sure
that buff gets set to 0
after you've printed everything out.
So like you could do buff is equivalent
to like null byte or something.
0 would actually
possibly work at the end.
Actually, what I would do is
something like this, an mcopy.
I don't remember how
exactly an mcopy works.
I believe it's-- well, let's see if it--
oh, Visual Studio.
Tell me.
I was really hoping it would.
COLTON OGDEN: I think you
can get that to happen
if you install the right extension.
NICK WONG: I know.
I really should spend more time
installing the right extensions
on these.
Destination, and we'll say source, size.
COLTON OGDEN: [? HiFiCS, ?]
thank you very much for joining.
NICK WONG: Actually we could just--
yeah, actually.
That's fine. [? Constantvoid*--
?] we'll do null byte.
And let's see what that ends up doing?
Whoa, that's not good.
Oh, string.h.
Good to know.
And I actually generally
prefer, I mean, generally I
prefer knowing which libraries I need.
But if I don't, then I would much
rather be told what to do there.
No argument where nonnull is required.
Oh, that's a bummer.
Where am I doing that?
What is the null nonnull argument?
COLTON OGDEN: Does it consider--
It doesn't consider the null terminator
character to be null, does it?
NICK WONG: I don't think so.
Oh, maybe it does, because there's
only three arguments required.
Well, that's kind of cool.
So what we could do--
maybe that's just-- actually,
what I could do is just null.
Let's see that does.
We'll find out.
Oh, it's even worse, but
maybe it'll work anyway.
Yeah, there we go.
Get some even worse behavior.
COLTON OGDEN: Safe.
NICK WONG: Yeah.
Very, very bad.
So if I wanted to, I could play
around with this and debug it,
and we'd be fine.
I am pretty confident
in saying that like,
it's just junk at the end of the buffer.
COLTON OGDEN:
[? TheDuckThough ?] is saying
memset buff 0 and then size of buff.
NICK WONG: Memset is a more useful
command there that we could use.
Yeah, there we go.
So that's gross.
We'll do 40 or 64, and then, oh,
well, another thing to consider
is that each of these buffers does
not have a null terminator at the end.
And so that might be causing
some of this problem.
We can do that here.
Memset, did he use the
actual syntax from memset?
Buff, 0, N, probably.
COLTON OGDEN: Buff, comma,
0, comma, size of buff.
NICK WONG: Cool.
That works.
COLTON OGDEN: And in your
case, as he says above.
NICK WONG: Cool.
My intuition is going to say that
that deals with my null1 terminator.
COLTON OGDEN: Yeah, OK.
C is hard.
NICK WONG: Yeah, no, it's a pain.
Yeah, and that is what
I will say is true,
in that the null terminator
is not going on here.
So what you could maybe do
is set this equal to the--
actually, yeah.
We're not going to deal with that
too much because it isn't necessarily
the main point of the stream, but what
I might recommend is setting everything
to null terminator, and
then proceed with the way
that we're actually doing it
here, and that should be fine.
Basically just copy in
up to negative n minus 1.
COLTON OGDEN: [? Brenda was ?]
asking, can you just
zero out buff before you read into it?
NICK WONG: Well, so actually,
I believe what's missing
here is our null terminator, because
you could do something like this
and I believe we'll end
up with the same behavior.
Oh, crap.
That's a bummer.
No, there aren't.
Yes, there are.
I'm a huge fan of blaming the compiler
until I realized what I did wrong,
and then I stop blaming the compiler.
I don't inherently see
what's wrong with that, but--
oh, because I, sure.
We could do this, then, where
you memset all of buff to 0 to N.
And I think we'll see the same behavior.
We can find out.
Yeah, we'll end up with the
same behavior, and that's fine.
My very strong guess is null
terminator dealing out here.
And it's OK.
We don't really have to
deal with it inherently.
But maybe it's something
to keep in mind.
Cool.
So after we've kind of dealt
with all of those things,
we now have something that allows us to
code kind of line by line, well, ish.
It allows us to take
in buffers and things
and allows us to kind of go through
our file one buffer length at a time.
However, it might be really
reasonable to us to--
COLTON OGDEN: [? Oh, and Brenda ?]
was saying your buffer is size n,
you're reading n bytes.
You don't have any room
for the null terminator.
NICK WONG: Correct.
So what I would recommend doing
is reading in n minus 1 bytes,
and setting the initial thing to
the null terminator, or all of it
is to null, And that should
actually end up being OK.
So you could do something like this,
actually, which I believe would work.
Yup.
COLTON OGDEN: Wow.
NICK WONG: Now, there is a
slight problem with that,
but that's OK, basically
the problem being
that I have appended this whack n.
And so what you can do is
here, and then we're good.
Thank you.
I thought about it and then didn't do it
because I thought it wasn't worthwhile.
COLTON OGDEN: And [INAUDIBLE]
is always like super help--
she helped me debug something
that I was doing on stream too
at one point, a physics
related thing I needed,
and I was like, what
is going on right now?
NICK WONG: It's one of those
things that are like, if you're
doing it on your own, never a problem.
You'll never face that problem.
But the second you do it--
COLTON OGDEN: It's only when you're
doing it in front of somebody,
or a lot of people.
NICK WONG: Exactly.
Yes, if you're ever doing it
in front of a lot of people,
they will immediately notice,
and your mind will lose itself,
and nothing will ever work.
So thank you.
Appreciate it.
But now we might want to do
something a little bit different.
We want to read actual line by lines.
I see someone, I think,
[? MyAlCat. ?] IDK what he is doing.
Looks like trial and error.
And you are very much correct.
That is a lot of what this
is, because we do code live,
so we don't actually prep anything,
as much as I would love to.
Generally, when I do
some sort of like seminar
or I guess lecture, general
educational tutorial,
I like to prep like an
entire script beforehand.
I like to prep a bunch
of code and I like
to basically not have to really worry
about coding in front of people.
However, in these streams,
we found that it's
really cool to be able to kind
of show that we're fallible too,
and we make all sorts of
mistakes, and I'm actually
very comfortable making
mistakes in front of people.
I do it constantly.
That's just my life, is just
making mistakes after mistakes.
COLTON OGDEN: Same.
I've gotten used to it
for the streams that I do.
NICK WONG: Exactly.
COLTON OGDEN: It's OK.
NICK WONG: It's totally reasonable.
COLTON OGDEN: The thing about
it is it's very flexible.
Because if you're into
a script and we want
to talk about some other random
topic and you veer from your script,
you could screw your script up big time.
NICK WONG: Exactly.
So I like this actually quite
a bit, and I don't necessarily
have any major problem with that.
COLTON OGDEN: [? MyAlCat, ?]
we all make those mistakes.
Yes, we do.
NICK WONG: Yeah, exactly.
COLTON OGDEN: [? MyAlCat, ?] yeah, no.
NICK WONG: Yeah, no, we're not insulted.
Trust me, we are pretty much
not insultable, I think.
COLTON OGDEN: I think so, yeah.
NICK WONG: We've been through
plenty, and you're all good.
We've been on the internet
before, and I mean,
I actually stream video games from time
to time, and people are much worse.
I mean, you guys are super nice.
You guys had the chance to
hack our WordPress website
last time, and did not put
like porn on the WordPress.
I was like, you know,
you guys are fantastic.
COLTON OGDEN: It could
have been much worse.
NICK WONG: It could
have been so much worse.
So we really appreciate the way
you guys actually interact with us.
COLTON OGDEN: Now it
would've been hilarious
and probably a meme.
It probably would've become a meme.
NICK WONG: We would've had
to just cut it out, I think.
COLTON OGDEN: If he would
have clipped it, though.
He would've clipped it.
NICK WONG: Exactly.
Our editors, I think, would
have cut that one out.
So yeah, no worry.
You will very rarely offend us,
I would argue probably never.
It would take quite a bit.
That's not a challenge like this.
Keep doing what you're doing.
That's good.
COLTON OGDEN: [? MyAlCat's ?]
asking what's your Twitch stream?
NICK WONG: Ah, so it's
pwrhausdacell It's
a modification of my like
general kind of coding handle.
COLTON OGDEN: OK, I
could write it for you.
NICK WONG: Yeah it's, P-W-R-H-A-U-S--
COLTON OGDEN: Oh, P-W-R-H-A-U-S?
NICK WONG: Yep.
D-A-C-E-L-L.
COLTON OGDEN: Is that
correct right there?
NICK WONG: Yep, that
should be it, I believe.
And that is my gaming twitch.
I like to kind of throw that out there.
It's a lot of fun.
[? The DuckThough ?] says
porn it is next time.
No.
We would think it's very funny, and--
COLTON OGDEN: We're
gonna lock that down.
NICK WONG: Yeah.
There probably won't
be another next time.
Probably the only time that we'll
ever let you guys just hack us.
Yeah.
So all right, we have
all of this going on.
Something that you might
be familiar with is fscanf.
And so we have file*, [?
constant*, ?] and then our buffer.
Oh, man.
So we're going to do
all sorts of things.
And you're reading this?
COLTON OGDEN: [? GoToPoopie ?] says,
I do 20% coding, 80% debugging.
NICK WONG: Yeah, that
sounds about right.
That might even be high on the coding.
I think I spend most of my time
debugging, and I kind of like it.
Like I like the iterative
process and kind
of like recalling things that I should
have known before and stuff like that.
I think that's very good to know.
I'm trying to think,
oh, a buffer size of 4
is probably not going to work there.
We'll say 1024.
That also might not work, and I
have a inkling of an reason why.
Yeah, there we go.
I think that's hilarious.
Oh, so I'm going to
stop it from running.
I always love when things like
that happen, because I think
that they're actually quite funny.
So what I basically did
was made a small change.
But if you go on to the
man page for fscanf,
OK, well, my computer has
decided to not work anymore.
Cool.
So we're going to wait while that
one catches up to what's going on.
If you'd like, you're
welcome to take some guesses
as to what went on, but basically,
the return value of fscanf
is not quite the same as
the return value for--
oh, great.
We're going to reopen that.
The return value for, what
was I using, fread, I believe.
And so that is something to kind of keep
in mind when you're actually-- oh, no.
Man, live streaming really
does kill the ability to type.
COLTON OGDEN: [? RedandGray, ?]
[? TheDuckThough, ?] and [? AsunaHQ, ?]
thank, all of you for following.
NICK WONG: Yes, thank you very much.
COLTON OGDEN: Oh, [? TheDuckThough ?]
is say, guys, use size up, please.
And this [? nonconst int ?] makes
my head ache by looking at it.
NICK WONG: Yes, so [? TheDuckThough ?]
points out a very good point,
which is that I have been using n and
they say [? nonconst int, ?] which
basically means that I am using this in
order to talk about the size of certain
things.
And so what they would argue
there is that size of 4 buff
would be a better choice,
and I very much agree.
That actually makes perfect sense.
So totally reasonable to do.
I would argue in this case,
it's relatively harmless
as far as differences go,
but definitely a good idea.
COLTON OGDEN: Yeah, like for smaller
program, not necessarily a big deal.
But if you're working
on a big code base,
obviously these kinds
of decisions make sense.
NICK WONG: Right, and I think
it is actually a good practice
to kind of hold yourself to that
sort of extensibility problem,
where if I were to move this variable
to like some sort of configuration file
and it's not necessarily
immediately accessible,
and I used it maybe a bunch of times
instead of just one, so in this case,
I use it twice.
Oh, wait, no.
That's a terrible idea.
There we go.
Then it would actually
be much worse to do.
I also realized a bunch of you guys
are saying you can't find my stream.
I might've misspelled it.
I will double check on
that and get back to you.
I don't usually like play any video
games when I'm here in college.
I only play when I'm back
home, so basically, I
don't really memorize it
super well, but there we go.
So now we can go back to what this
is actually doing, which is fscanf,
or scanf is actually what
we're probably going to use.
Sorry.
Although, fscanf in this case--
oh, actually, fscanf
works better in this case.
I was forgetting that we
aren't scanning from a stream.
We want to go all the
way down to return value,
and this will point out to
us what's going on exactly
with why this doesn't work.
I believe it returns null upon reaching
EOF, but we will see in a hot second.
I always-- well, there you go.
Scroll right past it.
There you go.
So we can actually say, wow,
that is not equal to EOF.
And now we can recompile our program--
sorry, the colors are
not quite as pretty--
and hopefully cut everything back out.
Now the reason that this
is a little bit interesting
is that I actually stripped
us of our new line.
So basically, what I ended
up doing by putting new line
here was I pulled out--
oh, I hovered over it
so you can see what I'm talking about.
I pulled that new line out of
the string and then printed it.
So that's why you get
kind of this weird blend.
If I refix that--
oh, cool.
Then we'll end up--
oh, maybe I didn't recompile that.
I'll clear this.
There we go.
Oh, well, that's a bummer.
Oh, I guess it strips it out on its own.
That's kind of good to know.
Didn't know that.
Ah, there we go.
Bummer.
So that then pulls in the entire buffer,
and I guess our buffer is pulling in--
oh, sure.
OK.
So then it tries to pull in
all sorts of interesting things
with how it actually decides
where a string starts or stops.
So we can do stuff like this, and
I believe that will fix that error.
Oh, maybe not.
Just kidding.
That's not what that's going to do.
Oh, well.
So that is kind of the right idea.
Somone asks, is that function safe, and
what you mean by that, I would assume,
is does it protect us
from buffer overflows
where we actually like insert
too much material by a little bit
too much into the buffer
that we're actually using,
and maybe return to some
other function start address.
And I would argue I don't believe
fscanf is safe, at least not from that,
though there are a lot
of functions that are,
and it's worth your while to
look up which ones are which.
I generally forget because I
don't build that much in C,
But it is worth looking at.
And something in general to consider
when you're doing, what do you say,
if you're doing any sort
of user input interaction,
then you want to be very careful of
what we would call undefined behavior.
So what [? TheDuckThough ?]
points out is
that this is a straight up
buffer overflow vulnerability.
I thoroughly agree.
Do not do this in order to interact with
anything that is like client facing.
If you're doing it to
interact with yourself,
and it's a small script that you're
writing only for your own use,
then I would question
why you're working in C.
But technically, that would be fine.
It is something very much
you want to keep in mind,
and it points to something else
that we are kind of seeing here,
where we're spending a lot of time kind
of dealing with how, in particular,
to do each of these things--
Sorry, where was I going with that?
Ah, how to kind of like nitpick and
go through each individual piece
is very much worthwhile,
and you can spend
a lot of time kind of really getting
into each one of these steps.
I would argue that in general,
any one of these steps
has something about it that we could
talk about and maybe optimize or fix,
but there is something to be said for
balancing it with what you are actually
trying to do.
And so in our case, we don't necessarily
care about how any one of these--
I guess it won't really
affect our end product,
which I forgot where we were
headed with that, but that's OK.
It's fine.
We will now actually talk
about making a makefile
so that I don't have to
keep typing this whole,
like going up two commands
and then rewriting stuff.
And that's something that's
kind of just worth looking at,
and I promised that we would
look at a little bit of assembly,
so we're going to write a much simpler
file that is going to copy things
over one byte at a time,
and that'll give us
something a little bit easier to look
at as far as what we're dealing with.
So what we're actually going to
do is rewrite this a little bit.
I believe it is just
read as the syscall.
So this is not using standard IO.
Oh, this is using standard IO,
but it's just read on its own.
And I think it takes in a
file descriptor, actually.
Let me check.
COLTON OGDEN: I don't remember
if I thanked [? RagashSharma ?]
for following, but thank you if so.
If not.
NICK WONG: Very cool.
So what we're actually going to do
is modify this program a little bit
in that we're going to deal with
syscalls rather than each of these.
So we're going to have an int
file descriptor is equal to open.
I think this takes in
the same arguments.
We'll find out.
Man open, man 2 open.
[? PatName. ?] Cool.
And what this is going to do is take
in our v1, which we know already
exists, and its flags are--
oh, right.
It takes in int flags.
I believe read only.
[? 0 RDONLY. ?] There you go.
Read only.
I don't remember where
those flags came from.
Oh, probably FCNT.
Right, that's what someone
pointed out earlier.
COLTON OGDEN: FlyingCircles,
thank you very much for calling.
NICK WONG: .H. I believe
that has this flag.
COLTON OGDEN: It's not an underscore.
NICK WONG: Ah, read only.
Sweet.
That's what I like to see.
So we're now going to actually open
this file and get a file descriptor.
Generally, if you wanted to
do actual error handling,
we are going to like check
for return of negative 1.
The standard for system calls is
when you have some sort of problem,
you return negative 1.
I'm going to kind of omit
error handling because I
don't want to run out of time, and
actually talk about each of the things
that we want to get through.
COLTON OGDEN: [? MeowCat ?]
makes a good point.
Syscall being equal to a system call.
NICK WONG: Ah, yes.
Sorry.
So, yes.
Oh, [? MeowCat. ?] Oh, I understand.
I was thinking [? MyAlCat, ?]
COLTON OGDEN: It might be.
NICK WONG: I think you generally
nail the pronunciations a lot better
than I do, so I'm
going to go with yours.
So yes, [? MeowCat ?]
points out that a system
call is the programmatic way in
which a computer program requests
a service from the kernel of the
operating system it is executed on.
That is a very good point, and what
that ends up actually meaning is--
what was I was going to say?
We have some sort of
protective control transfer
from user land, which is
where all of our processes
actually run, into kernel land or kind
of the kernel space, which is scary,
and all sorts of dangerous
things can happen there.
You have basically full
privilege over a computer.
So that's what we are0 talking
about anytime I say system call,
and the reason that I want
to kind of switch us over
into using direct
system calls is just so
that we can actually see a little bit
more low level what's exactly going on,
using programs like strace and mmap.
Otherwise, you wouldn't necessarily
need to use any of these,
unless you were dealing with
this particular kind of use case.
COLTON OGDEN: [? TheDuckThough ?]
just said protip, use mmap,
is that what you just said?
NICK WONG: Right.
So [? TheDuckThough ?]
says, protip, use mmap.
With that syscall, you can
directly map the file into memory
without needing to read
it into a buffer first.
That is a great point,
although not all files or file
descriptors are mmappable.
There are some which cannot
actually be mmapped--
into memory directly.
And mmap has some
problems that you might
face if you were trying
to maybe, for example,
implement your own buffering system.
So standard I/O uses a buffer cache,
which it basically says, and we'll
get into that in a second,
it allows us to speed up
kind of whatever is going
on with file read and write
or input/output, standard I/O. And that
buffer hash is, I think, 4,096 bytes.
And what that does is, anytime you
want to write something to file,
it's actually really expensive to
write something to a disk directly.
And what I mean by
expensive is that you have
to do some sort of control transfer.
I have to give power to the kernel.
The kernel's got to save state for
whatever it was previously running on.
And then it's going to
actually copy things over
into our disk, or solid
state drive or wherever
we are actually storing things.
And that's pretty tedious.
It's pretty intensive on your kernel.
So instead, what happens
is before we ever
actually pull some sort of
protective control transfer
and deal in kernel space,
we accumulate a bunch
of stuff in the standard I/O case.
You actually accumulate 4,096 bytes.
And then when you've hit that limit, or
when you have kind of closed the file
descriptor and you want
to get everything out,
then it will take that whole buffer
and flush it to actual memory.
That's for writing.
If you're reading, it
works kind of the same way
but in reverse, where when I'm
reading a bunch of bytes from memory,
it actually is to my advantage
to read a bunch of them at once,
even if I'm reading them one at a time.
We're going to see that in a hot second,
where if I try to read one at a time,
I again have to do these protected
control transfers back and forth.
And so what ends up
happening is it's going
to be a lot slower if I read
one at a time as opposed
to reading everything into a
buffer and then blowing it through.
COLTON OGDEN: All right, cool.
Michael Abrash is a very famous game
developer and worked on Quake and Doom
in the 1990s with id Software.
NICK WONG: Oh, sweet.
COLTON OGDEN: And he wrote
he wrote a book called,
I think it's the "Black Art
of Graphics Programming,"
and his first chapter is about
optimizing a sort of speller program,
kind of, like look at a list of words,
and instead of loading eight bytes,
like loading 1024 or 2048 bytes at once
is like two orders of magnitude faster.
It was on a Dos platform.
Like back in the day, that made a
difference between like one second
and like 30 seconds long
for your program running.
NICK WONG: That is crazy.
COLTON OGDEN: It's like exactly
what you're talking about.
NICK WONG: Yeah, no.
There's enormous
performance improvements
that can be gained by
using buffers efficiently.
COLTON OGDEN: Syscalls are
expensive, is basically the--
NICK WONG: Yeah.
Syscalls are very expensive.
COLTON OGDEN: [? AxAJaw, ?] thank
you very much for following as well.
NICK WONG: I'll say greater than 0.
All right, and then what
this should allow us to do
is, then write, which is also a syscall.
I believe it takes a file descriptor,
a buffer and also [? sum ?] size.
Oh, well, OK.
This will fail if N is not 1.
And N being 1 is actually
OK, but this is OK for us.
And then we are going to
close file descriptor.
Cool.
So then what we are also going
to do is touch a makefile,
and we're going to do
with that makefile.
So makefiles are really cool.
We're not going to talk about it too
much, but I'm going to kind of point
out what everything does because
it'll allow us to simplify
some of the other things we're doing.
So let's say that we
want to just make cat.
So this is kind of an interesting--
We'll call it like, Democat.
That' kind of cool.
And that requires, we'll call it cat.c.
Oh, no.
Thank you, autocomplete.
And then makefiles, after you give it
some sort of like pattern or keyword
that it can build, they also require
like what command is actually
run so we'll say dash o is cat.
Dash optimizedflags we'll
set to 1, and then cat.c.
And this should be-- oh, oops, sorry.
Democat, Democat and Democat.
That way we can kind of distinguish
it from the actual call cat.
And then what we can do is also
say for clean, I don't know,
usually you would remove object files
and other headers and things like that,
but we're going to kind of
just leave that as very simple.
Oh, sorry.
We don't need the R, but we need the
F. Well, I like having the F there.
And cool.
So what I can do with
this is I do make clean.
Democat doesn't exist,
but it would have run it.
We're also going to move
first.c into Democat.c.
Cool.
And we're going to, I guess, remove
cat as well, remove first, and remove--
actually, test.txt is fine.
So now that I've run make,
it should-- oh, nice.
I have a bunch of implicit
declarations of these functions.
I really thought they were
part of standard library.
They might be part of like sys.
We'll find out in a second.
Let's do man 2.
Read would work.
It doesn't really matter, as long
as it tells me which library.
Oh, whoops.
That's a library we need.
We might want to remove--
[INTERPOSING VOICES]
Yeah.
We don't need a bunch
of these libraries now,
so we're actually going
to kill a bunch of them.
I don't think I need those.
COLTON OGDEN: Everything breaks.
NICK WONG: It'll all
break now, which is great.
You need estd.h.
Cool.
And I believe that has them now.
Returning a return value of right.
Sure.
COLTON OGDEN: [? Brenda ?]
was saying that she, I
think she made a reference to
using Uni standard earlier.
I must have missed that.
NICK WONG: That's probably correct.
If you guys brought it
up, I'm sure you did.
Generally, you guys bring up-- oh, where
am I missing a return value of right?
Am I ignoring it somewhere?
Oh, OK.
So apparently, casting
that to void does not work.
Sure, I'll use it.
There you go.
I have used your return value.
Cool.
And then when we run Democat,
if I don't pass on the file,
it should tell me that
I didn't pass in a file,
and then I should also be able to--
oh, test.txt, and it did nothing.
Yay.
Oh, right.
It did actually do something.
I just forgot what it was doing.
So we read everything and then we wrote
it back out, which is kind of cool.
So this is actually interesting.
That did something kind of weird.
COLTON OGDEN: I read that
as Democrat.c for a second.
NICK WONG: We're running
Democrat on its own.
COLTON OGDEN: [? DiscoDamage, ?]
thank you for following.
NICK WONG: We're going to actually
write fprintf standard out of %s buffer.
And that should allow--
whoops.
Not what I wanted.
There we go.
democat test.txt.
Cool.
So we are now catting
everything out by one character
at a time, which is very interesting.
So someone asked, why are we
not importing standard library,
or like standard I/O I think I
actually do import both of those,
but I'm not using them at the moment.
And the reason for that--
actually, I am using
standard I/O. Whoops.
I needed that.
The reason for that is that I want
to put us at a slightly lower level
than those libraries would put us.
Because those are libraries have already
kind of created their own versions
of each of these things.
We were using them earlier, where
you have like fopen, fclose, things
like that.
I'm trying to have us deal a little
bit more with very low level, actual--
pretty much as close as
we can get to syscalls.
Sorry, syscalls themselves.
I don't know why I said
as close as we can get.
This is the closest we can get.
They are them.
This is exactly what
we're talking about.
And the reason for that is I want us
to be able to see a little bit more
about how each of these things
actually interact with our computer.
So we're going to deal with
something called strace.
strace is-- I think it
stands for trace syscalls.
And we're going to
strace.out as our output,
and then we're going to
run democat test.txt.
And strace is going to
write that to strace.out.
Most of these beginning ones, you'll see
mmap is a syscall that's run up here,
and there's a bunch of other stuff.
I think it's like line--
oh, there we go.
So the first line started--
COLTON OGDEN: These are all syscalls.
NICK WONG: These are all syscalls.
Right.
So the cool thing about
strace is it actually
tells you exactly which parameters
were passed to the syscall
itself, which is very cool.
And it tells you its return,
which I think is also very cool.
So if you're ever
debugging something where
you're working at a very low level,
then this is particularly useful.
So what we're looking at is openat--
sorry, I'm going to ignore the open.
That is technically what
our open does, but we're
dealing mostly with writes and reads.
So our reads here are
exactly what are going on.
You'll notice that there's
this write system call.
And if you look in our code, we
don't have a write system call.
None actually exist.
You might think, well, I thought we
were talking about only system calls.
And I will point us to
this function, fprintf
which does not actually explicitly
tell us that it uses a syscall.
However, in order to write to console,
you do actually need a system call.
So one of the great
inventions of the Linux system
is that you have everything as a
file, and as a file descriptor.
So I can describe the
console, and basically
standard in, standard out,
standard error, all as files.
In fact, they all have their
own standard file descriptors.
There is a variable, I believe, that is
like that particular file descriptor,
but we're not going to
necessarily deal with that.
I happen to know that it's
1, off the top of my head.
And so I can actually now write
to this file descriptor buf and n.
COLTON OGDEN: That's
actually what somebody said.
[? TheDuckThough ?] wrote
that in the chat there.
NICK WONG: Nice.
So [? TheDuckThough, ?] you kind of skip
ahead, I guess, and that's very cool.
Yeah.
Now we can explicitly tell what's
going on in our write system call.
However, if you'll notice
in this original strace.out,
there's only a single write system call.
That's going to change.
So what's going to happen
is, if I recompile this--
oh, right.
I have make now.
Oh, that's disgusting.
What?
Got to love the warning output.
COLTON OGDEN: [? Bhavic Knight ?]
says, "This is
starting to get a little overwhelming.
What are we trying to do?"
If you want to maybe reiterate the goal.
NICK WONG: Sure.
So basically what I'm
going to talk about
is we are building a version of Cat,
which is a kind of basic Linux commands
or bash commands that allows
us to take a files contents
and just print them out to console.
And then what we're
going to do from there
is see if we can kind of
consolidate some of these read
and writes a little bit.
We're not going to go all
the way into that, because it
would take a little bit too long.
But the basic concept is
pointing out that what's
going on underneath the hood is
actually really, really important.
And so it's kind of useful to us to see
that, even though we are working in C,
you can go at different
degrees of high or low level,
even within a language that
is notoriously low-level.
Hopefully that clarifies.
COLTON OGDEN: So taking it from
like standard I/O to using syscalls
to write using the kernel.
And maybe eventually
Assembly, if you have time.
NICK WONG: Yeah.
COLTON OGDEN: I'm not sure
what your plan is for that.
NICK WONG: Exactly.
So I guess, to go back to the comment
that was "libraries are for the weak,"
we're now basically
ignoring standard I/O.
However, I am apparently
implicitly declaring exit,
and I really don't feel
like dealing with that,
so we're actually going
to switch to return.
And that's fine for now.
So I'm going to get rid of standard
I/O, because we don't need that anymore.
And that failed.
Where do I-- oh, right.
Right.
This isn't actually going
to print anything to us now,
it'll just return 1.
We're kind of scrapping a
lot of stuff, so that things
are a little bit cleaner.
So basically, now our code is all system
calls, which is kind of interesting.
And what we're going to hopefully see
is that, when we run our code again,
our strace output should change.
So I'm going to bring us
back to this strace output.
And what I'd like to point out is that
Hello World got written as one system
call, and bye world also got written
as one system call of 13 and 11 bytes,
respectively.
However, that's going to
now shift, because now, we
write out each individual--
COLTON OGDEN: Character.
NICK WONG: --character.
And with a syscall, that means that
it has to be done individually.
And now we get what we would expect.
We get this kind of interleaved read
a character, write that character,
read a character, write the character,
read a character, write the character.
COLTON OGDEN: Same result,
just a lot less efficient.
NICK WONG: Exactly.
It's so much less efficient.
And so if you're wondering, why 1?
There's actually a standard set of
file descriptors for the first couple.
The first one is standard input--
sorry, standard output--
sorry, standard input.
I'm doubting myself.
Standard input is the
first file descriptors.
So that's 0.
Standard output is 1, and
then standard error is 2.
And those first three are
always going to be that way,
unless you do something crazy.
And so that's what we see
ending up happening here.
Now, something that can be
a little bit interesting
is, if we were to do this on something
that's really, really large, then
that might actually be kind of
problematic, because that file is
going to be read very, very slowly.
So let's say we wanted to cat out,
using our democat program, something
that was extremely large.
So let's take a file.
Let's do yes, Hello World.
I should put that in quotes.
Yes is a program that
just repeats things.
COLTON OGDEN:
[? TheDuckThough ?] pointed out,
if we wanted to be
clear with the number,
we get to use the function
fileno, and take an stdout.
NICK WONG: Right.
Fileno would also work.
And I believe there is actually a
library that declares those variables,
and it's something like
standard out fileno.
Yeah.
That would also work.
Actually, I would argue that
this is a much better system.
And generally, you'll want to do that.
For the same reason that we would use
like sizeof buf instead of n here.
Although, I am using n.
And there is no good reason
for that, at the moment.
That's a terrible practice, and
I'm not following my own advice.
So we will clarify that here.
COLTON OGDEN: [? TheDuckThough ?]
will be very pleased.
NICK WONG: Yes.
And I thoroughly agree.
So yes, Hello World is going to
print out a bunch of Hello Worlds.
And what we can do is,
let's say into head n--
we might need like 10--
is that a million?
Yeah.
We're going to pipe that into test.txt.
Broken pipe.
Cool.
And that makes sense.
I generally would recommend
using more of a while loop.
That's got to be an enormous file,
we'll see if it can actually load.
Nice.
It freaks out.
And we should have a million
lines of Hello World.
If we scroll all the way
down just for funsies,
we see we get to a million
lines of Hello World.
Yay.
So we have now built a test.txt,
and if I do democat test.txt,
and redirect that into dev/null, you'll
notice that it takes non-zero time.
And if we wanted to get
a real metric on that,
we could actually time
it, which is kind of cool.
So you know what that
run and see what happens.
COLTON OGDEN: [? 42Force, ?]
thank you for tuning in.
Says "Hello, Colton and Nick.
NICK WONG: Oh, that's awesome.
And we go through, and it took us
eight seconds, which is such a pain.
If we look at Hello World and see
H-E-L-L-O comma space W-O-R-L-D--
I think I have an exclamation point.
So we're at 12 right now.
Oh, no, I do not.
And then we get to 13 as our
size of the string that we have.
We repeated a string a million times.
So we have 13 million bytes in our file.
COLTON OGDEN: And they're translating
that to 30 million syscall, right?
NICK WONG: Yes.
[INTERPOSING VOICES]
So there actually--
COLTON OGDEN:
Well, the new line is one, [? right? ?]
NICK WONG: --26 million syscalls.
So that includes--
COLTON OGDEN: Oh, because
the read and write.
The read and write.
NICK WONG: We're reading
and writing, which is awful.
So what we can do is if I actually
cat test.txt, which is kind of funny,
you'll notice this is noticeably faster.
We have exactly 13 million
things going on here.
We have 13 million characters,
which means 13 million bytes,
for our purposes.
And you'll notice cat is--
substantially faster
is an understatement.
It's much, much faster.
COLTON OGDEN: Many orders
of magnitude faster.
NICK WONG: Yeah.
You can do a basic time on
cat, and it's not even close.
COLTON OGDEN: Almost
zero, complete zero.
NICK WONG: Yeah.
For our purposes, it's zero.
So that's kind of crazy.
So what we might want to do is see
if we can get a little bit closer
to the actual syscall that's going on.
And we know through our
strace output-- oops--
that we have this kind of
ridiculous interleaving of
reads and writes going
on, and that's horrifying.
COLTON OGDEN: Best choice ever made.
NICK WONG: Yeah.
COLTON OGDEN: [INAUDIBLE] but
best system program ever made.
NICK WONG: Best system
program ever made.
You get to wait for
hours and hours, if you
want to copy over a reasonable file.
So a reasonable suggestion might be,
OK, well, let's double the size of it.
So it should go substantially faster.
COLTON OGDEN:
[? UnsignedEd ?] suggested,
"Change your end to be 4,096.
NICK WONG: Sure.
Let's change it to the
size of the standard I/O
buffer, which is 4,096 bytes.
COLTON OGDEN: Is that defined as
a constant in a library, as well,
you think?
NICK WONG: I believe it is.
It is something that is
used by standard I/O.
We're ignoring the
return value of write.
We're going to just
pretend that that's OK.
We would actually make use of
these read and write return values,
if we were to set up
our own actual buffer.
Now, in this case, it doesn't
necessarily matter too much to us,
but we will get some
garbage output, I believe,
if we don't set this perfectly.
I think this will actually trigger
some weird output, which is fine.
So we run make.
And everything's up to date.
Now, if we run time of Democat
test into dev/null, way faster.
COLTON OGDEN: Wow.
NICK WONG: Substantially faster.
COLTON OGDEN: That's
faster than Cat, isn't it?
NICK WONG: It really is.
Yeah, I actually think
it was way faster.
COLTON OGDEN: Cat's twice--
NICK WONG: About half as--
COLTON OGDEN: You've made
a better version of cat.
Wow.
NICK WONG: Half speed.
Well, so correctness-wise,
we're actually not correct.
If you were to cat or democat--
here, we can actually do this.
Democat this into test2.txt and then
we do diff of test.txt and test2.txt.
They're not quite the same.
COLTON OGDEN: Interesting, it
has h at the very end by itself.
NICK WONG: Yeah.
That's a that's a pretty
big bummer for us.
That might be something--
COLTON OGDEN: Oh, it is because
the 4,096 at the very end,
it can't read that 4,096 bytes?
NICK WONG: So basically, it ends up
being that, let's say we have 4,096,
so the nearest multiple of
4,096 that's under 13 million--
I don't know off the top of my head.
COLTON OGDEN: So it just
won't call the fractional part
at the very end of that.
NICK WONG: Right.
It'll end up reading all of the bytes,
so we know that that part's correct.
But what it writes is actually a
buffer that has not been cleared.
So there is a part of that buffer that
has extra bytes in it from before,
and that's actually not quite right.
So if we look at test2.txt--
which is where we redirected
everything from our democat--
then if we cat test2.txt--
and we can trust that cat is correct.
I would argue that you're
pretty reasonably--
COLTON OGDEN: Probably, yeah.
NICK WONG: --there.
You'll notice it has
some extra lines in it.
Because of you cat test.txt, we
have exactly one million lines.
But test2.txt has a
couple of extra ones.
And those extra lines--
if we do 55 times 4,096.
I'll pull out a calculator
because my brain is fried.
It's been a long day at school.
COLTON OGDEN: If you can do it normally
in your head, that would be pretty--
NICK WONG: That'd be pretty cool.
I don't think I can.
Then basically, what you'll end up
noticing is that that's around--
COLTON OGDEN: 225,000?
NICK WONG: Yeah.
So we get 225,000, and
that basically means
that we are inserting 225,000 extra
bytes at the end of our cat program.
Not good at all, actually.
And so something else that
we can do is, let's say,
well, 8,092 should be a reasonable
next double for our n program.
And we can remake.
I'm going to just stop
searching through history.
Remake.
It's going to tell we're
ignoring write, and that's fine.
And then what I'm going to do is
time its output into test2.txt.
And this was actually
a little bit slower,
which is kind of
strange, because I would
have thought that, as we
doubled n over and over again,
I should get faster and faster,
because my buffer is now enormous.
And I'm certainly not below 8,092,
I have 13 million bytes in there.
So we're not exactly
sure what's going on,
and we might look to something
like strace to find out.
So let's go ahead and find my strace.
And we're actually going
to-- oh, right. test.txt.
I'm going to just wrap that into
dev/null, because I don't really feel
like having that put out to my screen.
So we're going to strace.out, and
you'll notice that what's going on here
is we are doing this explicit
write of 8,092 bytes every time.
And we go all the way through, and
that's exactly what's going on.
Things are kind of shifting around,
and everything's working seemingly.
And if we run this
again, but we remake--
so that we go back down to 4,096,
and we do make, and run that,
and go back here, same thing.
No immediate reason as to
why we would have something
actually be a little bit slower
when we ran it with 8,096.
COLTON OGDEN: It can't write more
than 4,096 bytes, because you said
that's the max size of the--
NICK WONG: That is
standard I/O's buffer,
but we're not using standard I/O.
We're doing our own system calls.
And so this is where
one of my professors
likes to point this out as
kind of a comical point.
Which is that you should do a lot
of trials anytime you run stuff.
COLTON OGDEN: I feel
like that's science.
NICK WONG: Yeah.
It's generally a good practice.
We might have had just a weird fluke.
So we ran a couple of trials.
They're all on the order of
0.00567, something like that.
So now we've remade this, and
we're going to keep running this.
And you'll notice, this is also that.
So then let's double check.
4,096.
And you'll notice that that
might have just been a fluke.
And actually, it wasn't a fluke.
There was something I did
deliberately, but very sneakily,
that caused that difference.
And that difference was that I
required the creation of a new file.
I did something like test2.txt,
and that was that extra overhead.
Because when I went to redirect into
a file that didn't already exist,
it had to create it, had
to open it for writing,
and then it had to send stuff to it.
And dev/null does not behave that way.
So we end up actually being
much faster if we're writing
the dev/null, as opposed to this.
And that performance change
can be seen right there.
You get back to that 0.027.
COLTON OGDEN: Makes sense.
NICK WONG: So actually, in concept,
if you went up high enough,
this should get very, very fast.
Now, you do have a good point
in that there is a buffer
that eventually this doesn't work for.
There is a buffer size in which we
eventually overmatch the buffer size,
and that can no longer be done.
COLTON OGDEN: Is that the
amount of addressable memory?
Or sorry, not the amount
of addressable memory--
NICK WONG: That would also be a limit.
You can only hold so much in memory.
COLTON OGDEN: Does-- every application
gets its own limited amount of memory,
right?
Or is it only with--
NICK WONG: It should.
COLTON OGDEN: --32-bit OSes
if they have the 2 gigabyte?
Because 32-bit operating systems only
have 2 gigabytes of addressable memory,
right?
NICK WONG: There's actually a
command to view how much memory
is allocated to any one process.
I don't know it off the top of my head.
Dang it.
There is a command to let you
see how much memory any process
should be allowed to have.
You can up that memory.
If you wanted to be really feisty, you
can up it to the entire installed RAM.
Wouldn't recommend it,
but you could do it.
However, you're probably
not going to hit
that before you hit the size of the
other caches between us and the disk.
Because the disk itself has a
cache that deals with the actual
writes to like some spinning hard drive.
And we will, generally,
hit that, but we won't
see it strace, because strace is just
telling us what the actual syscalls are
being called us.
And we can force it to
call them however we like.
However, there is some point at
which you will not get a performance
benefit to just doubling this n.
So we're going to keep it
kind of low, at like 4,096.
But otherwise, that
is a very good point.
COLTON OGDEN: [? TheDuckThough ?] is
making a point about branch prediction.
And I thought branch prediction--
NICK WONG: Ah, yes.
COLTON OGDEN: --was in the context
of just a single executable,
but it looks like they're making a point
about it running the same program over
and over again.
Is that the case, where
a branch prediction--
NICK WONG: Right.
So that one depends a little bit
on who developed your processor.
Because I have also interacted with them
mostly in the case of over one program
is runtime.
It learns throughout that program.
Something that is kind of
interesting about branch prediction
is it is roughly the cause of like
bugs like meltdown and spectre,
is because branch
prediction kind of opened up
this opportunity for certain timed
hijackings, which is kind of cool.
So if you're ever interested, there
is a really cool paper on meltdown,
I believe, and it basically walks you
through how it's supposed to work.
And then I see at the bottom
there-- ulimit, thank you.
I wanted to put unameit,
and that's not right.
[? ulimit ?] tells you
all sorts of things
about how things are
suppose be allocated,
and you can set those things, as well.
COLTON OGDEN: I've used that
to change the number of files
that I could have addressed
by one process at one time.
NICK WONG: Oh, very interesting.
COLTON OGDEN: Or, I guess could
opened by one process at one time.
But I didn't realize it
did other things as well.
NICK WONG: It does all sorts of things.
There's crazy amounts of
customizability in ulimit.
COLTON OGDEN: Interesting.
NICK WONG: And then there is some
discussion in our chat about the kernel
being in the stack.
That would be kind of an interesting
question, in that each process gets
its own stack, threads
have their own stacks,
and the kernel has its own stack.
And they all live in memory.
So stack is actually something
that's specific to a process, roughly
speaking.
And then the kernel is in the
memory, if I'm not mistaken.
Yeah.
The kernel's code lives
on in some sort of disk,
unless you are certain
operating systems.
I believe piCore and Arch Linux?
Not Arch Linux.
There's a different Linux distro
that runs entirely out of memory.
So in that case, what I said about it's
like code living in disk is not true.
Well, I guess it is kind of true,
but not relevant to the computer.
You could run the computer with
no hard drive, which is crazy.
But yes.
Almost everything that you're going
to be dealing with is in memory.
So cool.
Let's see.
There's a bunch of stuff
going on in the chat.
Always love the discussion.
COLTON OGDEN: Yeah, there's a lot.
We've been not reading
quite as many comments
[INTERPOSING VOICES]
NICK WONG: Yeah, just so we can
kind of get through some stuff.
COLTON OGDEN: Maybe we didn't
read quite enough today.
[? ISOTV ?] was saying that they need
to leave early, so thanks so much,
[? ISO, ?] for joining us.
NICK WONG: Thank you for joining us.
Yeah.
All right, cool.
So we have now written some of this.
So maybe we want to
implement a little bit
of our own kind of buffering system,
because we've said that correctness
is really not there at the moment.
So what we might want to do--
and we're going to kind of adjust
this a little bit, so that maybe our
write system calls are all granular,
but our read system
calls are totally fine.
Well, actually, we might run out
of time before that is even done.
So let me think about that.
Sure.
So we'll do some version of cat that
will improve our reading system calls,
but not necessarily our write ones.
So let's say that we're going to create
some sort of new function int write--
I will say demowrite, since
we're being consistent.
And what demowrite requires is some
sort of int file descriptor, as well as
some void star--
actually, we'll just say char
star buffer, and some size_t n.
And we want it to write out some number
of bytes to that file descriptor,
but we're going to just have
it do that one byte at a time.
So for int i equals zero
i is less than n, i plus--
you could do this in one
line, but for readability, I'm
going to put it all in here.
We're going to then call
the system column, which is
write of a file descriptor and buffer--
oops.
Buffer 1.
I'm sorry.
And this will be buffer at i.
So this will write
individual characters.
And we should be good on that.
So let's go ahead and verify
that demowrite now works.
Let's see if we can cat.
Oh, whoops.
Make first.
We get some errors.
Of course there's errors.
COLTON OGDEN: DLF1010, thank
you very much you're following.
Or just DFL10, if we're reading
it from binary to decimal.
I believe 1010 is 10.
NICK WONG: 1010--
COLTON OGDEN: Because it's 2, 8.
NICK WONG: 2 and 8, yeah.
Funny.
COLTON OGDEN: DFL10, then.
NICK WONG: Oh, wait.
That's kind of great.
10, 10, and 10.
Wow.
I had never really thought about that.
COLTON OGDEN: Now you'll never forget.
NICK WONG: Yeah, that's awesome.
It's just something that you don't
really think about that often.
COLTON OGDEN:
[? TheDuckThough, ?] thanks
for tossing in some
resources on how OS works.
He was talking about BIOS, bootloader,
kernel, [? UserLand ?] programs.
NICK WONG: That's awesome.
COLTON OGDEN: He posted a
link, osdev.org, it looks like.
NICK WONG: Sweet.
COLTON OGDEN: [? TheDuckThough ?] sounds
like they have a bit of experience
with systems and OS program.
NICK WONG: That is fantastic.
I think the more experience you get
with this sort of thing, the better.
COLTON OGDEN: Maybe even more.
A lot of this is somewhat
new. [? Syscalls ?]
aren't new, but a lot of sort of
looking at this as interesting.
NICK WONG: It's awesome.
So yeah, we have now built demowrite.
I believe we still ignore
that return, but that's fine.
I'm really not a huge
fan of having warnings,
so we're going to just
say int r, and then we're
going to just cast a void for r.
And that's not a great practice
for actual development.
If you were doing production-level
development, this would be terrible.
But we are kind of just
going after the concepts,
and so it's close enough,
for what we're trying to do.
And now, we want to make sure
that that actually still works.
So let's then just democat itself.
And we get gibberish.
COLTON OGDEN: That's great.
NICK WONG: Yeah, let's beautiful.
COLTON OGDEN: Ship it.
NICK WONG: Go.
Let's see what that does.
And so this is nothing along the
lines of what we want at the end here.
That's disgusting.
However, the things up
here, probably fine.
COLTON OGDEN: Are you
still reading 4,096?
NICK WONG: We are.
COLTON OGDEN: And the
program isn't that long.
NICK WONG: And this program
isn't quite that long.
COLTON OGDEN: So it's all garbage.
NICK WONG: That's all garbage.
COLTON OGDEN: [INAUDIBLE]
memory past the point.
NICK WONG: Yeah, exactly.
And if we wanted to verify that--
what this is, it's only 473 characters.
COLTON OGDEN: So we're reading
like 3,700 bytes of nonsense?
NICK WONG: Yeah.
Exactly.
It's just ridiculous
amounts of nonsense.
COLTON OGDEN: [INAUDIBLE]
in different memory.
[? KyLash, ?] thank you
very much for following.
NICK WONG: So now, we remake this
with a slightly smaller buffer size,
you'll notice that our
gibberish gets smaller.
So our hypothesis is probably correct.
So then what we're
going to want to do is
deal with how we actually
read things into that buffer.
And this is where we're going
to want to create a little bit
smarter read buffer.
So let's demoread--
COLTON OGDEN: Are we going
to check for end of file?
Is that going to be
part of the solution?
NICK WONG: Yeah, pretty much.
And basically, what we'll end up
doing is just kind of initializing
the entire buffer to nothing, to 0.
COLTON OGDEN: Oh, and then just
read in only until end of file--
NICK WONG: Yeah, exactly.
COLTON OGDEN: --and then it'll get
the null string, and then that means--
[CLICKING TONGUE]-- we're done.
NICK WONG: Yep.
And then we're good.
Now, if we want to create a
really smart read and write,
then maybe something that we would do
is create a customs data structure in C
that keeps track of maybe which
files descriptor it's attached to,
its own buffer, and which
position it's at in the buffer.
And actually, you'll
find that you require
roughly two or three of those
things in order to get that to work.
So basically, what ends
up happening is you
need to know where your imaginary
buffer is, in its beginning and its end.
And what I mean by that, it's
actually a little strange,
you want to know where it is, like what
its positions would be in the file.
And so you can actually think
about it as like, here's
your file, if I divide it up into
segments by buffer size, then
it makes a lot of sense for me, at any
time that I'm reading from the file,
I read in that entire buffer segment,
is what we would probably want to do.
COLTON OGDEN: Right.
NICK WONG: Now, demoread
is actually quite simple.
We don't have to do too much with it.
But let's say int demoread, and
we're going to read from some file--
int file descriptor.
We're going to want to read
into some char star buffer,
and we want to read in
some number of bytes.
COLTON OGDEN:
[? TheDuckThough ?] is saying,
"Let's go lower and
[? writekernel ?] driver.
NICK WONG: I would argue I don't
know how to do that, at the moment.
It's very possible that one day I will.
Very unlikely.
COLTON OGDEN: Are you taking
CS161, or did you take it already?
NICK WONG: Yeah, I will be
taking that next semester.
They might actually talk about that.
COLTON OGDEN: Yeah, I wonder if you
guys do that kind of stuff in there.
NICK WONG: Which I think is very cool.
COLTON OGDEN: CS161 is the operating
system class here at Harvard.
NICK WONG: Yes.
It's a class that I have waited for
quite some time to be able to take.
COLTON OGDEN: Your whole life.
NICK WONG: Yeah, I've been
very excited about taking that.
And so what we want demoread to do
is actually only read into the buffer
basically whatever it
could originally read.
So what we might do is some
sort of memset of buffer 0--
we'll actually do sizeof
buffer, to be consistent.
And then what we're going to try and
do is read up to n bytes into that.
So int r equals read of
file descriptor buffer n.
And you'll notice this
keeps the same usage.
And then we might return
something, r, here.
If I wanted to be a little bit more
concise, then I could return read.
COLTON OGDEN: Oh, you
forgot int in front of n.
NICK WONG: Oh, thank you.
Much appreciated.
COLTON OGDEN: Kudos
to [? TheDuckThough ?]
for pointing that out in the chat.
NICK WONG: Nice.
COLTON OGDEN: People are on top of it.
NICK WONG: Yeah.
People watching the stream
are always very on top of it.
It's very cool.
COLTON OGDEN: Thank goodness,
because otherwise, I know for myself,
I miss so much.
NICK WONG: Yeah.
I miss all sorts of things frequently.
Oh, memset is a-- is
that really a string?
I want to argue that
there is a syscall--
oh, no there isn't.
That doesn't make any sense.
If you're writing in memory,
there is no need for a syscall.
Of course.
And what I just mumbled to
myself is that I was like,
oh, there should be a syscall,
memcopy or memset or something.
They should be syscalls.
But of course, that
doesn't make any sense.
[? syscalls ?] deal with
going into the kernel space.
And in order to write
to RAM, I don't actually
need to touch the kernel,
which is why it's so fast.
So that would have
made very little sense,
and I'm really glad I noticed that.
Cool.
So we now are noticing that we
still have this problem of gibberish
at the very end.
And that's something that's totally
reasonable for us to expect,
in that we did do actually a memset of
size of the buffer into 0, blobdeeblah.
However, something that we might want
to do is something more like this.
So what we will do is we can capture
this output from demoread and use that.
And so what we can say
is something like this.
while true-- and we'll break
out of this using break.
while true int r equals
demoread of standard--
oh, wait.
No, we're using file descriptor.
Buffer size and size of buffer.
Now, this return from
demoread is the same
as the return from
read, which is how many
bytes we actually ended up reading.
And so what we might do is something
like demowrite of actually just r.
And from there, if r is
less than or equal to 0,
then we break out of this loop.
COLTON OGDEN: You don't have
access to true either, by the way,
because you're not
including standard bool.
NICK WONG: Oh, awesome.
Got to love that.
COLTON OGDEN: Yeah, while 1.
NICK WONG: A lot of these sorts of
things, I would argue, are not great.
And so it is our job to
point them out to you.
This is an example of something
that is not the best design.
COLTON OGDEN: You'd see it everywhere
in like the '90s and '80s, though.
NICK WONG: I know, and that's
the part that astonishes me,
is that that worked.
And you'll notice that this now
does exactly what we would think,
where it actually cats
the right thing out.
If we wanted to verify that test.txt to
test2.txt, we can go ahead and do that.
This will take a little while,
probably up to eight seconds or so.
COLTON OGDEN: [? Davins, ?]
"Lmao, what are booleans in 2019?"
NICK WONG: No need for booleans.
You just use 1 and 0.
Or if you're even crazier, maybe you
can find a way to use like empty string,
or like an empty list and--
I'm trying to think of
something creative--
and like the number 42 as true.
You could get into some
pretty weird things.
COLTON OGDEN: So what was it?
So r is going to be--
so you were breaking if r
is less than or equal to 0.
So in which case--
NICK WONG: Right.
COLTON OGDEN: --is that
going to be the case?
NICK WONG: So that will occur any time
that there is an error in demoread,
or when we get to end of file.
COLTON OGDEN: OK.
NICK WONG: And so both of those mean
that we break out of this while loop
and then close our file
descriptor, and exit.
COLTON OGDEN: And then
demoread is not going
to read the full 4,096 bytes if it's
at the end and it goes beyond 4,086?
NICK WONG: Right.
It'll read up to 4,086 bytes.
COLTON OGDEN: And that's in demoread.
Can we see which part of
that will be in demoread?
NICK WONG: Exactly.
So if we go into demoread, we
are setting our entire buffer
to 0, which is actually not
necessary, at the moment,
but I had it there originally.
And what this does is we
actually do some sort of int r
equals the read of our file descriptor
that we pass it into the buffer
up to n bytes.
And that's what we looking for.
And it returns up to n, or
negative 1, if there was an error.
COLTON OGDEN: OK.
And then so the actual function call
of it, we're reading this-- oh, 1,024.
OK.
NICK WONG: Right.
COLTON OGDEN: OK, I got it.
NICK WONG: Yeah.
Exactly.
And so you'll notice that that program
to cat everything into test2.txt
took quite some time.
And so we're going to
do strace one more time
and see what happened, because
that is a little bit strange.
Excuse me.
And if you are looking at these and
you're saying, oh, well, obviously this
would take a very long
time, you'd be very right.
It is quite obvious,
if you can remember,
if you scroll up to demowrite, we
write everything one byte at a time.
And that is where you actually
see this get quite slow.
Now, if your recall,
our original program
that read and wrote
everything one byte at a time,
that was eight seconds or so.
This one does not seem
to be only eight seconds.
It takes quite some time.
COLTON OGDEN: [INAUDIBLE].
NICK WONG: And we're going to kind of--
well, strace.out is going to be
quite large, in the sense that we are
reading and writing 13 million lines.
Now, you'll notice we
did this read of 1,024.
That was great.
And then we proceeded to write
1,024 times, which is a huge pain.
So if we wanted to speed
things up a little bit,
then we could still increase this
buffer size of ours to 4,096.
And we can do this.
Oh, wait.
I have to remake.
We go through, and it
will get slightly faster.
Now, strace is going-- oh, I
shouldn't run that with strace.
What I actually wanted to run
was this, to kind of point out
to us just how much faster it got.
Now, this should be some weird hybrid
of eight seconds and 0.0015 seconds.
Now, we might end up with something
a little bit different from that.
We could hypothesize
as to why that's true.
And then the next step
would obviously be
to write a write buffer, which
is a little bit different,
in that whenever you
go to close the file,
you also need to flush
the buffer to the file.
And that would require a little
bit more work on our part.
I guess I could have actually just
had that be our goal the whole way,
but we have now, at this
point in time, talked
about how to build a version of
cat using the standard in and out,
standard I/O.
And that's kind of cool.
It doesn't have all the features and
functionality of cat, but it does work.
And then we went and
moved to something that
is a little bit of a hybrid between
low-level syscalls and standard I/O.
And then we went all the way
into a syscall version of cat
that has some of its features, in
that it can read pretty quickly,
it has a buffered read, but
its writing is pretty terrible.
And so that is something that you might
be interested in exploring a little bit
more.
It's very much a
worthwhile exercise to see
if you can implement
different kinds of buffer,
as opposed to the one we're
doing here, which would roughly
translate to a single-slot buffer.
We have a single slot that we are using
to read into and then write out of.
However, we could very easily
build a multi-slot buffer,
where I read into one slot, and then
into another, maybe up to four or more.
And maybe have some reason and policy
by which we kick something out of a slot
and fill it with a new set of data.
There's all sorts of things
you can do with that,
and I would certainly recommend
trying out all sorts of things
with how you actually deal
with how your computer runs.
I think it's very cool.
So that concludes all that I have,
as far as the stream goes, actually.
COLTON OGDEN: We are at the
2 hour and 10 minute mark.
So thanks, everybody who came in
today to check out the stream.
I'm going to take us to the wide shot.
Actually, no, screensaver.
We've got to do a screensaver.
That's the--
NICK WONG: That is very important.
COLTON OGDEN: We've taken
it out with that every time.
We'll leave it on this
for just a minute,
while we take some last questions.
So apologies if we didn't get
everybody's questions today.
NICK WONG: Yes.
COLTON OGDEN: There was
a lot, which is awesome.
I really appreciate everybody's
involvement today, everybody tuning in.
And a lot of people tuned
in really early too--
NICK WONG: Yeah, that was awesome.
COLTON OGDEN: --which was super awesome.
Join us for the next one.
Actually, I'm curious, it's the end
of the semester coming up pretty soon.
This might actually be the
last stream until 2019--
NICK WONG: Wow.
COLTON OGDEN: --which
is kind of ridiculous.
NICK WONG: That's crazy.
COLTON OGDEN: Yeah, we
have the fair this week,
and then next week everybody's leaving.
I'm leaving town, actually.
I'm going to California.
NICK WONG: Hey.
COLTON OGDEN: You're from California--
NICK WONG: Oh, sweet.
COLTON OGDEN: --so you'll
be going to California.
NICK WONG: I'll be going
to California, too.
COLTON OGDEN: Nick and I
are going to California.
I don't have a streaming
setup over there,
so we might not have
another stream until 2019.
But if that's the case, it'll
be January 2nd or 3rd probably.
And then we'll be doing weekly
streams, like multiple times per week,
going after that.
NICK WONG: Yeah.
COLTON OGDEN: You'll be
part of that, I presume.
NICK WONG: No, I will
certainly be there.
We have like Raspberry Pi is coming up.
COLTON OGDEN: Raspberry Pi.
NICK WONG: We'll deal with some hardware
stuff, maybe even get a camera on one.
We'll have, I think,
Kali Linux coming up.
COLTON OGDEN: Oh, the Kali Linux.
Yeah, the White Hat--
NICK WONG: Live CTF going on.
We will have--
I don't know.
Did David do a Docker one?
COLTON OGDEN: He's going
to do a Docker one.
Yeah, he wants to do a Docker one.
NICK WONG: OK, then
that one will be there.
We have all sorts of things going on.
Oh, Bitcoin we'll talk about.
COLTON OGDEN: Oh, yes.
True.
NICK WONG: We'll talk about Bitcoin.
And I guess we'll lump Blockchain
into that, just because that's also
very interesting.
Maybe you like an API build,
like build a RESTful API.
COLTON OGDEN: Oh, a RESTful
API would be super cool.
NICK WONG: That'd be kind of cool.
COLTON OGDEN: Yeah, get
the web devs in there.
NICK WONG: All of our
web devs will be happy.
We might even build a Swift app.
COLTON OGDEN: Oh, a
Swift app would be cool.
NICK WONG: I think
that'd be really cool.
I had totally forgot about that
until the [? CSVD ?] Hackathon.
Then everyone was like,
oh, Swift, I love Swift.
And I don't really like Swift that
much, but I do love building apps in it,
and I think that's really cool.
So I think that'd pretty fun.
COLTON OGDEN: Yeah.
Yeah, all of the things.
NICK WONG: Yeah.
We'll go into all sorts of things.
COLTON OGDEN: Yeah.
We have a lot coming
in, and then I have--
we'll be doing probably once or
twice a week gaming-related--
NICK WONG: Sweet.
COLTON OGDEN: --programming
tutorials and streams.
So tune in for those, starting
around January 2nd or 3rd.
And I'll get you to figure out
what the first day will be.
We'll be on the Facebook group,
so definitely message us.
If we don't see you or
hear from you until then,
well, definitely have a
great holiday yourself--
NICK WONG: Yeah.
COLTON OGDEN: --wherever
you are in the world,
and whatever holiday you
might be celebrating--
NICK WONG: People are
all over the place.
It's awesome.
COLTON OGDEN: Yeah, we've got people
all over the world, United States
and then abroad.
We have India, we have Italy,
Greece, and all sorts of places.
New Zealand.
[? Brenda ?] repping New
Zealand is a big one.
NICK WONG: Literally all over the world.
COLTON OGDEN: Belgium,
Netherlands, all kinds of places.
Lots of great message
in the chat saying--
NICK WONG: Yeah, thank you guys so much.
COLTON OGDEN: Happy holidays.
Yeah, same to all of you.
[? Bhavic Knight, ?] [? MeowCat, ?]
[? 42Force, ?] [? Erenay, ?]
[? 42Anto42, ?] [? UnsignedEd, ?]
[? ShaneHughes1972, ?] California--
NICK WONG: California.
COLTON OGDEN: It says California.
NICK WONG: Me too, yeah.
COLTON OGDEN: California's--
NICK WONG: California.
COLTON OGDEN: --good stuff.
California's good stuff.
And then [? AzayAndre, ?]
[? Fatma, ?] yeah.
NICK WONG: Yeah.
Thank you guys very much.
COLTON OGDEN: It's going to be--
NICK WONG: Oh, shoot.
I forgot that someone in the chat said,
what did you do in binary exploitation?
And I totally forgot to talk
about binary functions and things.
We'll mention that.
We'll do a whole stream on it maybe.
COLTON OGDEN: We could do a part two.
We'll do a part two maybe on that.
There's just so--
NICK WONG: There's so many things to do.
COLTON OGDEN: --much
to cover, and two hours
is not a lot of time for all of that.
NICK WONG: No, it really is not.
COLTON OGDEN: But yeah.
Thanks, everybody again, so much.
This has been CS50 on
Twitch with Nick Wong.
My name is Colton Ogden,
and tune in next time.
Tune in in January, if we don't
do another scream until then.
And have an awesome holiday season.
NICK WONG: Yeah.
COLTON OGDEN: All right.
NICK WONG: Enjoy.
See you guys.
COLTON OGDEN: Happy holidays from CS50.
