Type Punning in C++

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what's up guys my name is Jonah welcome back to my C++ series so today we're gonna be talking all about type punning in C++ and type planning is really just a fancy term for just us kind of getting around the type system in C++ so C++ is a strongly typed language which means that we have a type system we don't declare everything as auto I mean we kind of can because of that kit word but in other languages like JavaScript there are no kind of sense of variable types really and we just have we don't need to declare a variable type when we create a variable and when we accept it in its parameters into functions or anything like that we don't have a type system really but it's a plus plus of course we do have a type system we have to declare things as integers or doubles or bullying's or structs or classes all that stuff when we actually create variables however this type system is not really enforced as strongly as it is in other languages such as Java where it's really hard to get around types and even c-sharp but you can do it but it's a bit more work in C++ whilst types are kind of enforced by the compiler you can directly access memory which means that you can kind of say that hang on a minute I know that at the moment in my code I've been using this type as say an integer but actually I'm gonna just grab that memory that same memory and just treat it as a double now or as a class or something like that and you can just get around the type system really easily now whether what you should is going to again depend on your actual circumstance in some cases you absolutely should not circumvent the type system because the type system is there for a reason and you probably don't want to be playing around with a 2-month unless you have a good reason but in other cases it's totally okay to do that for example let's just say we had a class and we wanted to write it out as a stream of bytes well instead of kind of going through everything as assuming it's like a structure of primitive types it doesn't have pointers to other places in memory we can just kind of reinterpret that entire struct or class or whatever we have as just a byte array and just write that out or stream it somewhere right we don't have to even care about what types are in it so we know the size we can just get the get to get the data access it and then just put it somewhere so in a lot of cases it is really useful and it means that it's kind of that raw I guess low level access that is why I really like C++ and why suppose was is so effective in applications where performance is required anyway not talking let's just dive in take a look at a few examples this is something that I use quite often so you'll probably see it in other videos and especially like in the OpenGL serious and the game end deserts and all that so you'll see plenty of this this is just gonna be a basic overview but let's just dive in and see what we can do okay so in that first example I kind of declared an integer well I just said that I had an integer and then I just wanted to treat it as a double well of course in this case that's probably gonna result in and pretty weird-looking double and not something that you want to do but again just to demonstrate how this works I'll show you anyway we're going to make it double we're gonna call it value and we're gonna set it equal to a that's kind of step one now first of all you can see it works right everything seems to work fine if we were to print this out like this and I even put a breakpoint over here get at five you can see what we get is 50 okay interesting reasonable I guess I mean it converted our integer to a double now so it's 50 let's take a look at the memory so I'll go debug Windows memory and memory 1 I'm gonna go to the memory address of a and take a look at what is in there ok cool 32 zero zero zero zero zero zero okay makes sense 32 is 50 in hexadecimal now let's take a look at the memory address of value now first of all is going to have a different memory address the second of all well we know how many bytes it is it's eight bytes look at that it's completely different I mean 49 49 and 40 over here and like what's going on it's it's not even it's not it's not the same memory at all because what's actually done is this just actually done a conversion it's converted an int into a double because that's what happens if you do something like this now in this case it was an implicit conversion meaning we didn't actually tell it to convert anything if we wanted to be explicit we could write double a like that which is fine I mean it doesn't get anything in this case we don't have to write double here because it will do an implicit but if we wanted to be explicit this is actually what's happening is converting that a from being an integer into an actual double now what if we wanted to just take that existing memory we saw 32 and then zero zero zero zero zero zero in our memory I wouldn't take that same memory but I just want that memory to be treated as a double how do I do that well the first thing to do that that we need to do there are a few ways actually but this is the kind of wrong way I guess we take the memory dose of a and then we cast that to a double pointer so and a double by double pointer I mean obviously a double pointer not two pointers now this part here is of course just taking the memory address of a so this gives us an integer pointer and then we're converting that into pointer into a double pointer and then we obviously need to get back to having a double so how do we go from pointer to the actual type we dereference it and that's what we get so this is this looks a bit weird maybe if it's the first time you've seen it but essentially what we're doing here is we're type punting our integer into a double so if we hit f5 now let's see what we get okay so it's a pretty weird-looking double I mean it's negative nine point two eight plus sixty-one so yeah whatever clearly not something that we'd probably want to do but again it's just an example if we take a look at the memory address of a you can see that of course it has 32 like that and if we take it the memory address of B oh sorry I'll value you can see what we have over here now what you also see is if you remember that we have eight bytes of double the rest is our initialize memory because what we've done here is something pretty bad because these are different sizes right I mean we've taken a four byte integer and kind of decided to a double so what that's done since we've converted an int pointer into a double pointer and then dereferenced it that's actually gone ahead and looked four bytes past our integer and grabbed that memory which is not our memory it's not the memory we have for integer so this is very bad and it could even cause a crash in some circumstance it's definitely something you want do I mean we've copied that memory into a new double value blog so that's safe so we haven't written and we if we can't at this point even if we do write to value we're not going to be writing to memory this on ours but we definitely have read from memory that's not ours that's not good let's take a look at a more practical example so what I'm going to do now of course if you didn't want to just just a quick note if you didn't want to actually create a whole new variable and you just wanted to access this int as if it was a double then you can just add an ampersand to the end of this double here which will just reference it and not copy it into a whole new variable and that way you will be actually editing this integer memory so that is dangerous because if I decide to write something like 0 into here then guess what it's actually going to write 8 bytes instead of 4 but we only have space before this might even crash so let's take a look at a more practical example what if I have a struct called entity and this has two variables in X Y now we know really say I hope you know that if we have let's just initializes to 5 and 8 if we have something like this in memory then really all that struct is is like it it is it is made up of those two integers it has literally those two integers and that's it if we look at its memory you can see we have 5 & 8 that's it the struct itself does not contain any kind of padding any kind of data whatever if it's an am C struct then there has to be at least one bites the will be something in there because we need to be able to address that memory and we can't address it it's not there so we have to have at least one byte instructive and if it is empty but if we have variables in there like in x and y that struct is just two integers that's all it is there's no like extra data that says this is an entity struct it's not how any of that works it's just the two integers so what we can do here is we can actually just treat this empty struct as an int array or maybe just extract one of its integers by not even doing it so you don't why it's take a look so I could just say a dot X and that would give me my X variable but what I could do also is just say well let's make it a read out of it so this will be a raw array say in point up call this out of my position equals the memory address of a and then just cost that Twitter points up like that and now if I wanted to print this out I'll just write it as CDC out position zero and then comma position one like that as if it was Justin all right and you can see there I have it five eight I mean I'm accessing it like it was an array because I've converted it into an array basically I've said that this entity memory address contains the beginning of an int array right or it just contains a pointer to an integer and then I've just looked one integer ahead using the same kind of method what I could do is something even crazier perhaps let's just say I wanted to get that Y variable out of it now of course any sane person would just write that and fact that's probably what I would write as a well I mean man because I'm pretty sane but what you could do is you could get the memory address off e like that converted into maybe like a char pointer again not sure why you would but let's just say that you did that is of course of one byte in size so we need to go four bytes forward like that and then convert that memory into an int pointer and then dereference that and then we have access to Y so let's go ahead and print this crazy piece of card like that and I'll check that out we get a which is of course the Y position of the entity but the point is what we've done here is we're just kind of just reverted to raw memory operation so I mean that simples Clause does really well which is why it's such a powerful language one of the big reasons why it is such a powerful language because it has that kind of it can manipulate memory really easily and really freely and memory is by far one of the biggest things we actually have to deal with when we're actually programming so whilst this code probably should never exist like in real applications because it's crazy and of course in this case you can just use a dot Y it can be very useful if you don't want to deal with kind of copying or conversions because again if we wanted this as an array well we can't like if you let's just say you wanted to create you know how did I get positions or whatever as an int array well how would you do that well I mean I guess like well you would have to kind of do it well this is not an array so I have to just create like a new int array right now because this isn't a function and you know we're not taking in like some kind of memory to put that that array into we probably need to create our own array which means we need to heap allocated and then copy that and I don't even want to write this code it's disgusting it's terribly slow it's awful what I could do instead is just return well I don't know memory address of X right now this of course really depends on the user not trying to do something like position two because there is no third element and that's going to go away bus to memory however you can see that now what I have access to if I fall you get positions he is an actual int array with two elements in it that I can access and I haven't I can also write to it so I can say position zero equals two and I've changed the x-coordinate of my entity but also I you know I haven't copy anything I haven't copied memory redundantly I've just linking to the same memory I'm just choosing a different way to actually interpret that memory if you don't want to deal with the raw cost so you can use reinterpret class to do exactly the same thing we will have a video for simple space costs in the future reason I haven't done one yet it's because I don't use them too often - you see style passed most of the time I probably should use if I spot star class but what are you gonna do anyway that is basically tie pudding it's just us being able to say I'm gonna treat this memory I have as a different type than it actually is and you can see if we can do that really freely all we really need to do is just get that type as a pointer and then cost it to a different pointer and then we can dereference it if we need to and just deal with it anyway I hope you guys enjoy this video if you did please hit the like button let me know what you think about try planning and this type system and why like why try planning is useful and why you love it so much or you do I hated I don't know well how do you feel about it leave your thoughts in the comment section below if you want to support the series please go to Petra non compos - to Cherno huge shout out as always to all my lovely supporters this series would not be here without you guys so thank you and I'll see you next time goodbye [Music]
Info
Channel: undefined
Views: 72,642
Rating: 4.9405546 out of 5
Keywords: thecherno, thechernoproject, cherno, c++, programming, gamedev, game development, learn c++, c++ tutorial, type, type punning, type punning in c++, type system, pointers, memory, reinterpret
Id: 8egZ_5GA9Bc
Channel Id: undefined
Length: 13min 20sec (800 seconds)
Published: Sun Apr 29 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.