Type Punning in C++

แชร์
ฝัง
  • เผยแพร่เมื่อ 28 ก.ย. 2024
  • Patreon ► / thecherno
    Twitter ► / thecherno
    Instagram ► / thecherno
    Discord ► thecherno.com/...
    Series Playlist ► thecherno.com/cpp
    Thank you to the following Patreon supporters:
    - Dominic Pace
    - Kevin Gregory Agwaze
    - Sébastien Bervoets
    - Tobias Humig
    - Peter Siegmund
    - Kerem Demirer
    Gear I use:
    -----------------
    BEST laptop for programming! ► geni.us/pakTES
    My FAVOURITE keyboard for programming! ► geni.us/zNhB
    FAVOURITE monitors for programming! ► geni.us/Ig6KBq
    MAIN Camera ► geni.us/t6xyDRO
    MAIN Lens ► geni.us/xGoDWT
    Second Camera ► geni.us/CYUQ
    Microphone ► geni.us/wqO6g7K

ความคิดเห็น • 334

  • @vertigo6982
    @vertigo6982 5 ปีที่แล้ว +342

    This must be the "scary basement" of C++.

    • @xKaihatsu
      @xKaihatsu 3 ปีที่แล้ว +10

      Type punning is real fun to mess around with.

  • @patulle2154
    @patulle2154 6 ปีที่แล้ว +174

    "I guess I am pretty sane"
    I have my doubts

    • @TrogdorPlays
      @TrogdorPlays 5 ปีที่แล้ว +11

      Remember that coffee intro? :P

  • @michaelclift6849
    @michaelclift6849 3 ปีที่แล้ว +31

    Structure padding / member alignment, definitely needed a mention here.

  • @OzieCargile
    @OzieCargile 3 ปีที่แล้ว +64

    I love how you are getting into the advanced features of C++ in such a straightforward way. These have long been shrouded in verbose mystery, and you have such a beautiful way of demystifying them in simple terms. Thank you for being an amazing teacher.

  • @WyMustIGo
    @WyMustIGo ปีที่แล้ว +15

    Before some newbie programmer does any of those pointer tricks, you should also teach them about packing because when you start mixing types inside a struct and/or switching platforms, the code will not work if the padding changes. I've been in the industry as a ASM/C/C++ programmer since the mid 80s, and to be honest other than when messing around, people don't do stuff like that in production code (unless they want to be fired).

  • @michaldvorak2230
    @michaldvorak2230 6 ปีที่แล้ว +215

    I clicked for C++ puns.. utterly disappointed :|

    • @poryg5350
      @poryg5350 5 ปีที่แล้ว +2

      In programming you have to construct everything yourself, I thought I knew that... Unless of course there's a preconstructed library.

    • @aryanmediratta955
      @aryanmediratta955 5 ปีที่แล้ว +13

      Variables can have multiple "meanings" depending on the datatypes they are cast to.
      Puns, you see?

    • @briannoel5698
      @briannoel5698 3 ปีที่แล้ว +13

      I think you mean, utterly "disappointered" ;)
      Sorry...

  • @Kricen
    @Kricen 6 ปีที่แล้ว +38

    I think beginners often get into trouble with strong types and C++ allows tricks like this which makes people try to go around the type system for no good reason in most cases. When you become more experienced you have less and safer type conversions, because the type system starts to make sense.

    • @loli42
      @loli42 4 ปีที่แล้ว +16

      idk why everyone thinks that "beginners" just go around type punning shit for no reason. what do you think they're doing? you think static typing is so difficult a concept to grasp that, instead of just using the type system like they're supposed to, novice programmers just think it's a good idea to store all their scalars as an int64 and fucking type pun into them? two year old comment nigga ass.

    • @zes3813
      @zes3813 3 ปีที่แล้ว

      wrggg

    • @puppergump4117
      @puppergump4117 2 ปีที่แล้ว

      @@loli42 Maybe someone who doesn't even know what a type pun is (like me) would try to use % on a double by first using a long long then casting that way too big long long into a double without losing a bunch of data. As far as I know, cpp doesn't give warnings for bad or unnecessary casting.

    • @loli42
      @loli42 2 ปีที่แล้ว

      @@puppergump4117 that's not type punning, it's casting, and c++ compilers most certainly do emit warnings for implicit narrowing conversions because msvc won't shut the fuck up about it

    • @puppergump4117
      @puppergump4117 2 ปีที่แล้ว

      @@loli42 I obviously know that. Which is why I explicitly said 'casting'. After casting loses double data, I try type punning. And from MY experience, there were no warnings.

  • @litmus3742
    @litmus3742 2 ปีที่แล้ว +10

    It's worth noting that type punning via arbitrary types, even if they're the same size has undefined behaviour. You can argue that it might appear to work in some situations or with optimisations turned off, but it's generally just not a good idea. Enabling optimisations, compiling to a different platform, adding a comment above the code etc... could break the code. Your initial Entity example for example violates the strict aliasing rule and isn't legal C++.

    • @oschonrock
      @oschonrock 9 หลายเดือนก่อน +1

      all the examples are UB

    • @kolosso305
      @kolosso305 หลายเดือนก่อน

      thanks for the warning!

  • @AKatyal90
    @AKatyal90 2 ปีที่แล้ว

    All your videos are super useful, they have just the right length, neither too short, nor too long

  • @deepakprajapati2635
    @deepakprajapati2635 3 ปีที่แล้ว +1

    mind blown, made my love for C++ increase even more!!

  • @darthnegativehunter8659
    @darthnegativehunter8659 4 ปีที่แล้ว +7

    you didn't mention "offsetof"
    it's a really useful function for type punning.

  • @lukenukem8028
    @lukenukem8028 4 ปีที่แล้ว +2

    [11:16] This is one way C++ blows my mind.

  • @damian_smith
    @damian_smith ปีที่แล้ว

    Really useful to know - thank you.

  • @UserUser-pv2wo
    @UserUser-pv2wo 4 ปีที่แล้ว

    this is the super important topic. I studied it initially from Jerry Cain's lectures @ stanford....

  • @zxnnightstalker2289
    @zxnnightstalker2289 2 ปีที่แล้ว

    I love type punning really!.

  • @Byynx
    @Byynx ปีที่แล้ว

    Don't be scared if you don't understand, keep learning C++ and with time you'll comeback and all of this will make sense and be easy.

  • @peiciuioan9612
    @peiciuioan9612 6 ปีที่แล้ว +1

    Thanks for this video!

  • @ranasalman4972
    @ranasalman4972 8 หลายเดือนก่อน

    when it clicked, I was like "WOW Damn that's amazing :)"

  • @kissmyoradora83
    @kissmyoradora83 ปีที่แล้ว +4

    Type punning is great for me when I'm storing data in a memory IC one byte at a time on a micro-controller. Turn a double/struct into a char array of the data-types total sizeof() and loop through.

  • @christopherprobst-ranly6357
    @christopherprobst-ranly6357 ปีที่แล้ว

    That hand waiving...

  • @kobimizrahi9397
    @kobimizrahi9397 6 ปีที่แล้ว +1

    Love your videos. Could you make one on how to package and distribute a c++ app soon?

  • @friendlycanadian4771
    @friendlycanadian4771 3 ปีที่แล้ว

    auto pun = "yes"

  • @Howtheheckarehandleswit
    @Howtheheckarehandleswit 2 ปีที่แล้ว

    You talked about type punning without even mentioning the genius Quake Fast Inverse Square Root algorithm?

  • @batchnerd
    @batchnerd ปีที่แล้ว

    Could you technically use this to modify private class variables you wouldn't have access to normally? I guess I could test it out but it's an interesting thought.

  • @ali51717
    @ali51717 3 ปีที่แล้ว

    Personally, I use it sometimes to access private members of the class, outside the class.
    not useful, but yeah, sometimes and only sometimes it is useful

  • @relytheone853
    @relytheone853 10 หลายเดือนก่อน

    I wish I had some of your projects code. People, would you share?

  • @ShadowaOsu
    @ShadowaOsu 4 ปีที่แล้ว +4

    or you could just do
    Entity e = { 5, 8 };
    auto& [x, y] = e;
    and wouldn't have to worry about memory stuff

  • @LS-cb7lg
    @LS-cb7lg 3 ปีที่แล้ว

    cherno: "i dont even want to write this code, its disgusting, its terrible, its slow"
    me, coming from a lang like java: " :'| "

  • @ashutoshpandey-jf9gd
    @ashutoshpandey-jf9gd 6 ปีที่แล้ว

    Hi Cherno,
    first thing your video are very good but speed is little bit faster.
    If we work on 32bit OS, and we want to save an address of variable then we need 4bytes i.e
    char c;
    char *ptr=&c;
    so to save the address of char c we need at least 4 byte right?
    now my question is as per C++ standard empty class size is 1byte due to differentiating via address.
    So how compile save empty size struct or class memory into 1 byte.

  • @max_ishere
    @max_ishere 4 ปีที่แล้ว

    So I can obfuscate like this?

  • @zoeythebee1779
    @zoeythebee1779 3 ปีที่แล้ว

    Brain hurts

  • @videofountain
    @videofountain 5 ปีที่แล้ว +1

    The utility of this video, as currently marketed, is close to zero. One remedy would be to rename the video to something such as … Identifying and Avoiding Abominations in C++. Aghast of the Rotten Deadly Cast.

  • @memcpy7
    @memcpy7 2 ปีที่แล้ว

    I really hate the lazy palm outro in his last C++ videos!

  • @superheaton
    @superheaton 4 ปีที่แล้ว

    7:15 how do you delete lines 10-13 so quick, it looks like one shortcut key?

  • @mariogalindoq
    @mariogalindoq 6 ปีที่แล้ว +6

    Hi Cherno. You are doing a good job, but I recommend you to be more c++11 or better c++17. For example, use the universal initializer: int a{3}; instead of int a=3;. Another example, use i = static_cast3.5; instead of i = (int)3.5;. I think your videos could be obsolete very soon if you keep using c++98. C++11 has 7 years old so, now it can be considered classic and secure. Good luck and hope this will help you.

    • @mariogalindoq
      @mariogalindoq 6 ปีที่แล้ว

      Yes, I saw in this particular video that you said that probably you should use the new cast expressions. This "cast" example was a coincidence because my recommendation is for all of yours videos and in many different aspects: "Use more c++17".

    • @Gaivs
      @Gaivs 6 ปีที่แล้ว

      Do you have any good resources for c++17? I haven't really been able to figure out what's new or how it's better than the older versions that I'm used

    • @seditt5146
      @seditt5146 6 ปีที่แล้ว +4

      Yeah.... IDK, I think it would be better for you young people to learn the traditional way of doing things instead of everyone trying to learn the new... and generally pointless way of doing it. What is gained above with Static Cast. Is it worth the sloppiness it gives to your code? A{3} is another example ... Is ugly... its confusing. I get flack for Raw pointers alot because I am oldschool, but I manage my memory which is easy as all hell in OOP... I see little need for Smart pointers unless... I need smart pointers. You are asking the entire C++ Community to accept higher overhead standards for no other real reason other then... Its new... Please provide stronger arguments for switching to an uglier and ever so slightly degraded performance of newer versions of C++.

    • @kocho4242
      @kocho4242 6 ปีที่แล้ว +1

      Sedit T
      1. When you investigate a bug and you suspect it can be related to casting, it's much easier to find in the code all your occurances of static_cast than C way of casting with (int). Generally speaking, static_cast is safer. Why? Google is your friend :-)
      2. More smart pointers == less memory leaks.
      3. C++11 has been released 7 years ago. Features it contains have been added for a reason, not for a fun. It's really high time to learn and start using them, because today many projects are being developed according to them. When you apply for a C++ job, you will be certainly asked for C++11/C++14. At least in project I'm involved in, C++14 is widely used and old fashioned C++ is not recommended. On the other hand, I think C++11 is much more difficult and complex than C++98.

    • @seditt5146
      @seditt5146 6 ปีที่แล้ว +2

      "2. More smart pointers == less memory leaks."
      Of course it does, it also comes with overhead as does much of modern C++ in one form or another. I hear much talk about the overhead is neglectable however I benchmark almost everything I do and there is indeed overhead, sometimes half speed of what standard C++ offers.
      However... This is highly platform dependent as I have run some of my benchmarks on my system and seen half speed ( range based for loops using std::vector ) where as it ran faster on some other peoples systems.
      (" It's really high time to learn and start using them, ")
      I agree... I also believe you have that backwards. Modern C++ is all that is taught anymore so its not me that needs to learn and use them. I do, when performance and need calls for it. However which is many times the case, and esp when new comers are coming over from Java, they are clueless how to handle their memory. The know nothing about pointers and have become so reliant on modern compilers to do it all for them that they have lost many tools from their toolbox by blindly following professors, who insist for no other reasons then they do not really have the time to fully explain older complex issues and its best to not confuse, in thinking that older C++ should NEVER be used.
      I know a coder who is very very good at what he does and I tend to go to him when I have any issue because he knows what he is doing. He is a rather popular youtuber matter of fact however I remember one day he came to me because he was totally oblivious to how to use Macros because professors anymore tell people NEVER to use them which is absurd, they save time and can be a powerful debug tool as well as making it very easy to make alterations. for instance, I use _COS/_SIN macro quite often when I need to switch and profile between implementations of cos and sin. One line of code changed and I have essentially updated an entire 5k+ LOC project.
      I am not here to debate if Modern C++ is better or not or if it has reasons for its existence, of course it does, what I am against is pushing it as the only option as it limits the programmers significantly.

  • @jacobschmidt
    @jacobschmidt 4 ปีที่แล้ว +2

    he's teaching a lot of ub...

  • @weltmeister
    @weltmeister 2 ปีที่แล้ว

    Retitle video to "wtf" pls

  • @softwareengineer.9992
    @softwareengineer.9992 4 ปีที่แล้ว

    If possible please teach me

  • @theguy-j6j
    @theguy-j6j 2 หลายเดือนก่อน

    you guess you are?

  • @karterianin
    @karterianin 6 ปีที่แล้ว +1

    Sound is not alignement with video...

  • @20270813978095210
    @20270813978095210 5 ปีที่แล้ว

    11:10 haha

  • @StefanGliga48
    @StefanGliga48 6 ปีที่แล้ว +1

    What about punning with unions?They're a little bit cleaner.

    • @seditt5146
      @seditt5146 6 ปีที่แล้ว

      Yes Sir.... I try to anticipate anytime I might need it like Vec3 class of mine I have Union for the X,Y,Z to also include a float array, (as well as RGB component) because OpenGL likes to have my Vectors as an array sometimes where as I like to use X,Y ,Z most of the time. Same with Matrices I can extract my Columns much easier as well as also having access to my X,Y,Z,W and the entire Elements[16]

  • @treyquattro
    @treyquattro 6 ปีที่แล้ว

    so is being trans karyotype punning?

  • @cipherxen2
    @cipherxen2 4 ปีที่แล้ว +3

    Assembly/C/C++ programming is like brain surgery. Only qualified experts should do it. It's not for everyone.

  • @nimrodhawk4011
    @nimrodhawk4011 4 ปีที่แล้ว +105

    This is one of the most essential videos Cherno has done, imo. It really demonstrates the fundamentals and power of C++ memory usage/manipulation. Good stuff, thanks for the “pointers”.

    • @student99bg
      @student99bg ปีที่แล้ว +8

      He didn't mention undefined behavior in this video. A lot of code here has undefined behavior. You need to walk on a thin line if you want to write code like this and avoid undefined behavior. I have read Joe Zbiciak's answers and comments on Quora about what is defined and what is undefined (at least for C, usually what is true for C is also true for C++ but here we are on a thin ice territory). If you don't know by heart what is and what isn't undefined behavior when it comes to things like this you can't guess it.

  • @h.hristov
    @h.hristov 6 ปีที่แล้ว

    Thanks for this video!

  • @rakma525
    @rakma525 2 ปีที่แล้ว +73

    This technique is used in Quake's notorious fast inverse square root function. It converts a float into a long in order to use bit manipulation.

    • @andrefaustino5514
      @andrefaustino5514 ปีที่แล้ว +6

      I finally understood better what was done in that Quake video

    • @4dillusions
      @4dillusions ปีที่แล้ว

      But Carmack said "SIMD is not a useful thing", and now we use glm instead of bitwise magic. :D

    • @magellan124
      @magellan124 11 หลายเดือนก่อน +1

      Carmack is a genius

    • @softed
      @softed 10 หลายเดือนก่อน

      ​@@magellan124 carmack didn't invent it, he found out about it from someone else

    • @magellan124
      @magellan124 10 หลายเดือนก่อน

      @@softed who?

  • @DashwoodIce9
    @DashwoodIce9 4 ปีที่แล้ว +79

    This is my favorite episode in the series. If someone asks me how can programming make someone feel powerful, I'm going to refer them here.

    • @AbarajithanGnaneswaran
      @AbarajithanGnaneswaran 3 ปีที่แล้ว +3

      I do this regularly and I know exactly what you mean!

    • @jakub7321
      @jakub7321 3 ปีที่แล้ว +8

      This is my favourite comment. If someone asks me if I have seen a good comment before, I'm going to refer them here.

    • @mykolatetiuk6661
      @mykolatetiuk6661 3 ปีที่แล้ว +7

      ​@@jakub7321 This is my favorite sub-comment, which points to the favorite comment. If anyone asks me about why C++ is so wonderful, I'll tell them about pointers and point to this sub-comment, which sill refer to the parent comment.

    • @igorthelight
      @igorthelight 3 ปีที่แล้ว +6

      @@mykolatetiuk6661 I really don't want to prove something but here is a C# equivalent code. Maybe someone doesn't even know that you could do that in C# too ;-)
      using System;
      class Program
      {
      struct Entity
      {
      public int x, y;
      }
      unsafe static void Main()
      {
      Entity e = new Entity{x = 5, y = 8};
      int* position = (int*)&e;
      int y = *(int*)((byte*)&e + 4);
      Console.WriteLine(position[0] + ", " + position[1]);
      Console.WriteLine(y);
      Console.ReadLine();
      }
      }

  • @Xxp0r
    @Xxp0r 6 ปีที่แล้ว +32

    I love type punning network packets, it allows me to overlay a struct to parse out its members (without the padding of course).

  • @Gunslinger962
    @Gunslinger962 6 ปีที่แล้ว +98

    *insert puns here*

    • @jpsilver3510
      @jpsilver3510 6 ปีที่แล้ว +37

      I should of asked for her namespace because now i have a STD

    • @Gunslinger962
      @Gunslinger962 6 ปีที่แล้ว +4

      Jp Silver epic 😂😂

    • @asefew1
      @asefew1 6 ปีที่แล้ว +13

      Type puns here

    • @MrSushant3
      @MrSushant3 6 ปีที่แล้ว +4

      @Jp Silver , I *c* what you did there. 😁

    • @jpsilver3510
      @jpsilver3510 6 ปีที่แล้ว

      xD xD

  • @jimmylander2089
    @jimmylander2089 4 ปีที่แล้ว +15

    The way you passed the ints as an array blew my mind

  • @lincolnsand5127
    @lincolnsand5127 4 ปีที่แล้ว +32

    This is undefined behavior btw. You should be very careful with this because different compilers will act in different ways. You can run into issues relating to lifetimes and alignment.

    • @OFfic3R1K
      @OFfic3R1K 4 ปีที่แล้ว +7

      The whole experience of programming in C can be summarized as undefined behaviour. As far as I remember alignment isn't really an issue, of course it would be if you wrote the code that was demonstrated, but there are easy ways to deal with alignment if you actually want to dive into this unique flavour of BDSM.

    • @lincolnsand5127
      @lincolnsand5127 4 ปีที่แล้ว +5

      @@OFfic3R1K The best way to legally type pun in C++ is to use memcpy (which is legal since a new object is created. This means the strict aliasing rules aren't violated). We do get std::bit_cast though which will allow for type punning casts and it can be used in constexpr situations.

    • @wusuoliu5431
      @wusuoliu5431 2 ปีที่แล้ว

      ​@@lincolnsand5127 @OFfic3RiK Great discussion! As a newbie I have a question. If our code is absolutely free of alignment and Endian problems, could type punning still cause unexpected errors? I saw a stack overflow example claiming that, when compiler optimization is in place, under strict aliasing rule, the compiler might assume two pointers of different types point to different places, and thus decide the writes via the 1st pointer do not affect the 2nd pointer and its pointed value, so it generates machine code which may not register-load the 2nd pointed value in time, and thus lead to catastrophe. However some other people were saying the post was wrong. Do you think this as an legitimate issue?

    • @lincolnsand5127
      @lincolnsand5127 2 ปีที่แล้ว

      @@wusuoliu5431 Well. It depends. gcc and clang have a flag called -fno-strict-aliasing. If you don't use that flag, compiler optimizations might break your code. If you have the flag, *only* hardware-specific things will (e.g. some architectures don't allow unaligned loads).

  • @raymondyoo5461
    @raymondyoo5461 6 ปีที่แล้ว +11

    I learn much further and deeper with youe videos than I could learn during my class.
    Concise explanation for complicated concepts.
    I will review C++ with these videos and I hope I get more used to C++.
    Thank you very much for your work!

  • @pascalrottier4783
    @pascalrottier4783 4 ปีที่แล้ว +12

    I noticed the memory was little-endian. I assume endianness is a factor to consider here. A 4 character string, interpreted as and int, will give you radically different results on a Linux x86 machine compared to a Linux Sparc machine. Or am I wrong?

    • @gabiold
      @gabiold 3 ปีที่แล้ว +2

      Not always, but usually yes. ;-)
      Endianness is not an operating system thing, so accessing memory as int pointer to index the int struct elements should work the same on Linux x86 too and on Sparc, MIPS, etc too without worrying these.
      But this is only true, if you cast elements back to the types they originally was and if you work with the data in the same program only.
      The problem starts, when these data leave your program in any way.
      If you serialize an int, send the chars over a network into a different (endianness) machine, then you read it back there and cast back to an int. Then it will be backwards. This is the reason why there are htons() and nthos() functions exists for TCP/IP networking. The network byte order is standardized, and if the system you compile on is in the same byteorder then these functions do nothing, if it is different then they swap the data.
      Another issue is that sizeof(int) is implementation-defined. It could very probably happen that if you send ints from a PC to a 8-bit microcontroller where int could be just 8-bits then you also have a problem. Theoretically you could even have a problem, when you save data to a file, and open it on the exact same machine and OS, but with a different program, which might be compiled with a different compiler. This is why one should avoid using int, and use fixed size types like uint32_t instead.
      Another issue is memory alignment and structs. Some architectures, ARM for example doesn't like unaligned memory access, so an 32-bit integer should reside on 4 byte address boundary only.
      So if you have a struct { char, uint32_t } then you have 8 byte allocated, the first byte is a char, 3 byte padding, then 4 bytes of int.
      If you serialize this struct by indexing it's memory you may expect that you have 5 bytes of data, but instead you have 8, because of the padding.
      This is a problem when you want to map a struct to a hardware register or some kind of network data.
      Some compilers have a possibility to tell them to generate packed-struct to avoid padding. Non-standard, non-portable, of course. attribute((packed)) in GCC, #pragma pack in others, etc...
      And if the target CPU really can't do unaligned access, then the compiler will generate two aligned reads for that unaligned int then shifts the bits to assemble it for you. Performance issue...
      All of this can happen and this is why this considered dangerous and you should not do it unless you are develop a low-level system in a specific environment and you know exactly what are you doing.

    • @gabrielbarrantes6946
      @gabrielbarrantes6946 9 หลายเดือนก่อน

      Yeah, this is not portable!

    • @NosebergEatzbugsVonShekelstein
      @NosebergEatzbugsVonShekelstein หลายเดือนก่อน

      ​@@gabrielbarrantes6946It is portable if you convert it to network byte order before you work on it then convert it back.

  • @Classic336
    @Classic336 4 ปีที่แล้ว +61

    The "double value = *(double*)&a;" reminded me of
    "i = * ( long * ) &y; // evil floating point bit level hacking"
    from Quake III Arena source code.

    • @lincolnsand5127
      @lincolnsand5127 4 ปีที่แล้ว +2

      Both are not legal ways to type pun in C or C++. So. They are at least similar in that way.

    • @SandFoxling
      @SandFoxling 3 ปีที่แล้ว +2

      You refer to it like its some popular joke not some random line of code burried within a game's source code... I love it XD

    • @totallynuts7595
      @totallynuts7595 3 ปีที่แล้ว +4

      @@SandFoxling it is a popular joke, what do you mean? The quake 3 fast inverse square root code is legendary. (For the comments more than the actual code)

    • @SandFoxling
      @SandFoxling 3 ปีที่แล้ว

      ​@@totallynuts7595 I figured, I guess I'm not old enough... I have read 'masters of doom' but that's about the extent of my knowledge on the early days of ID and their legendary feats.
      I guess you still would have to call that joke within a specific circle to actually cast it into a popular type.

    • @totallynuts7595
      @totallynuts7595 3 ปีที่แล้ว

      @@SandFoxling i'm not that old either, compared to the games. I just like Doom and Quake

  • @andrey7268
    @andrey7268 3 ปีที่แล้ว +3

    This video is missing a big red neon warning at the very beginning that most things described in it are actually undefined behavior and should never be done. This code *will* break and cause a lot of grief.

  • @graemehdev
    @graemehdev 5 ปีที่แล้ว +5

    Dodgy talking about that without mentioning strict aliasing aka what happens when you think you changed your struct values, but the compiler just updated a register. Suddenly the memory address is not the value you think it is

  • @Tovi7
    @Tovi7 6 ปีที่แล้ว +8

    I love your video's. Have been sort of binge watching the C++ series. But on this video you kinda lost me. Looking at this code feels so dirty :p I don't immediately see the practical application in a real codebase. Seems like it could be the source of bugs if you're not careful. Looking forward to the casting video's however!

  • @oschonrock
    @oschonrock 9 หลายเดือนก่อน +1

    sweet.. I think everything (like every example) in this video is undefined behaviour....
    just thought that that should be pointed out.

  • @martincets8334
    @martincets8334 6 ปีที่แล้ว +7

    Hey Cherno, It would be really cool if you covered the subject of unions in a video.

  • @Hamid1Reza
    @Hamid1Reza ปีที่แล้ว +1

    I think we can do all or some of them with reinterpret_cast.
    Which one is better?

  • @lukenukem8028
    @lukenukem8028 4 ปีที่แล้ว +5

    Watching this makes me hate type punning.
    I vaguely knew about it's usage, but didn't know it's name.

  • @MsJavaWolf
    @MsJavaWolf 5 ปีที่แล้ว +4

    Afaik converting structs to arrays isn't always safe, because og alignment.

  • @mm1979dk
    @mm1979dk 6 ปีที่แล้ว +5

    I hate it because this is C way of messing about, it is not portable and when you mess up (or try it on a different platform), the compiler will not help with type checking, because you broke all the rules of sane coding. Bad, bad advice.

    • @ineednochannelyoutube5384
      @ineednochannelyoutube5384 5 ปีที่แล้ว +1

      Its low level access. By definition its complicated and easy to mess up.
      This is the point of c. You can do this sort of shit.

  • @michaurbanski5961
    @michaurbanski5961 6 ปีที่แล้ว +4

    Hey!
    I've started watching your videos only recently and I love the way you explain things, everything is so clear here unlike most YT channels.
    In one of the c++ videos (how to write a c++ class) you wrote a LOG class but at the end said "that is absolutely not how i would write a log class". If that's possible in the future, I would love to see a video or a series of videos where you write an actual short project step by step.
    Have a nice day and keep up the great work :)

  • @KaenguruGaming1
    @KaenguruGaming1 6 ปีที่แล้ว +10

    This is undefined behavior. It violates the strict aliasing rules. This is only allowed if you are punning to std::byte, char, unsinged char, or a type "similiar" to the one you are punning from. Use memcpy instead. It'll get optimized away so don't worry about overhead.

    • @xFlRSTx
      @xFlRSTx 2 ปีที่แล้ว

      wdym by similar

  • @9SMTM6
    @9SMTM6 5 ปีที่แล้ว +2

    This is very interesting and a nice demonstration of 'C++ is no magic', but at the same time you should probably make it clearer that this should NOT be used in projects by anyone but experts, and even these should think like 4 times about it. In most cases the possible performance penalty is probably to be preferred over possible insecurities and other problems that this stuff can cause.
    Theres some situations I might think of using this, i.e. to convert a 3 element array (interpreted as 3D vector) to an interpreting struct {double x,y,z} but TBH I miss experience to try to do this in any but a POC.
    Edit: So basically the Unions in the very next video. Neat, was this video meant mostly as a explanation?

  • @MsKarlason
    @MsKarlason 5 ปีที่แล้ว +2

    Can compiler choose how organize this in memory and brake it?

  • @FrostyChilli
    @FrostyChilli ปีที่แล้ว +1

    A very nice video! This actually provided me a different angle to understanding pointers.
    When I follow along with the code I usually add comments about what Cherno said and what I thought.
    I hope the following exempt will help someone else get a different view on pointers as well.
    So, in my mind...a pointer is like a tool that specifies:
    1. How many bytes to read? (int pointer reads 4 bytes, double pointer reads 8 bytes, a pointer of a struct with size 27 bytes reads 27 bytes).
    2. From where should we start reading those amounts of bytes?
    This kinds of makes our issue clear (talking about "double value = *(double*)&a;" here). We initialized a variable of size 4 bytes (int a = 50). So 4 bytes somewhere in memory were allocated to represent the value 50. In order to read these 4 bytes, we need a 'reader' that knows to read exactly 4 bytes (int pointer), and also from where to read them. However, we constructed a 'reader' that reads 8 bytes (double pointer). The starting position of these readers are the same. However, the 8 byte reader reads 4 bytes more than was specified when we wrote int a. And so, since the other half was not specified, in addition to the 4 specified bytes, we also read unspecified bytes from there. And this will lead to us getting an unexpected result. While the end result does correctly allocate 8 bytes (the newly created double variable), the issue is that we read 4 additional bytes, which we did not specify ourselves, and thus the outcome will be random.

    • @Byynx
      @Byynx ปีที่แล้ว

      Try to think that when you cast pointers or a variable adress (&var) you are just saying to the compiler "Hey use this memory adress to read or write and trust me that everything will be fine". You can have 10 different vars/pointers pointing, reading and writting to that same memory space that the compiler doesn't care if you this C-Style casting. But if you do a mistake you'll have undifined behaviour or memory leaks will emerge.

  • @VargoViaty
    @VargoViaty 4 ปีที่แล้ว +2

    I cant believe I'm watching this right now lol.
    I spent two nights to actually come up with this same idea to solve a problem and now I find out it was actually a thing

  • @robertmoats1890
    @robertmoats1890 ปีที่แล้ว

    Watch out for the type punning police! They really don't like it when you break out these tools. Did you know that some compilers require special options to be deactivated in order to even do these things in c++? Some circles are trying to dumb down the language and put us in a safety box, but I'm totally in support of having such tools. We obviously need to be responsible with them, but they are absolutely necessary to do certain things efficiently. For instance, good luck designing a memory pool without using type punning. Or some type of array/allocator that manually calls constructors as they are needed.

  • @jontaylor1586
    @jontaylor1586 ปีที่แล้ว

    I know this is an old video and my comment is going to get lost in the sands of time. But saying that JavaScript doesn't really have a type system isn't right. It's just a dynamically typed language vs a statically typed language like C++. Types are all resolved at runtime instead of compile time. Other languages, like Python, work similarly.

  • @diegotames
    @diegotames ปีที่แล้ว

    This demostrates the amazing power of knowing C++, also, I guess that we could use this capability to achieve something like Arena Allocation, right?

  • @DanielLiljeberg
    @DanielLiljeberg 6 ปีที่แล้ว +3

    After all these years I'm still not sure about how I feel about C-style casts contra static_cast, dynamic_cast, const_cast and reinterpret_cast in C++ code. Since the C style cast is not very clear about which type of cast will occur, since it depends on the data types, I feel the more verbose C++ style casts helps when I read code that isn't mine. Because, and correct me if I'm wrong. The C style cast actually tries the various C++-style casts in order, until it finds one that works.

  • @gabrielbarrantes6946
    @gabrielbarrantes6946 9 หลายเดือนก่อน

    Actually structs can have some padding, if the types don't aling nicely, compiler can add some padding to improve performance...

  • @Destrio_Fury
    @Destrio_Fury 2 ปีที่แล้ว

    The messier it gets, the more I like it.
    It could/must/would be use to desirealiz objects and stream them in file or over connection... Just thinking.🤔

  • @hishamsomroz6913
    @hishamsomroz6913 3 ปีที่แล้ว

    int y = *(int*((char*)&e+4); wtf lol. Here come's a bit scary part, Just to access that freakin y. lol

  • @soniablanche5672
    @soniablanche5672 8 หลายเดือนก่อน

    type punning is actually possible in javascript with ArrayBuffer and TypedArray

  • @il2626
    @il2626 2 ปีที่แล้ว

    Idk how useful of type punning that example is tho as you could just
    convert it to int pointer and access as array. If somewhere for some
    reason a int isn't 4 bytes you got a problem aswell but ig thats in
    general with type punning. 9:58

  • @electronlabs2802
    @electronlabs2802 7 หลายเดือนก่อน

    you haven't mentioned that in some cases compiler might add padding between between x and y in the struct.

  • @ultimatesoup
    @ultimatesoup ปีที่แล้ว

    Generic memory pools to take advantage of cache locality and memory fragmentation are times when it's absolutely necessary to directly tell the compiler how to interpret a type

  • @sharpparadox9563
    @sharpparadox9563 11 หลายเดือนก่อน

    Now i dont know at the moment what i would do with that but i feellike i can write some troll code accessing everything by casting to a charpointer and moving it around

  • @RX7GSLSEowner
    @RX7GSLSEowner 5 ปีที่แล้ว +1

    Yeah do this type (pun intended) of thing all of the time in C. Normal fare really. I get that a lot of "modern programmers" arf over that notion but there are times when it is useful. Like with arguments over which language is best, I find such criticism to shed more heat than light. I digress. Good video.

  • @kargaroc386
    @kargaroc386 2 ปีที่แล้ว

    I really insanely don't like how the only way to do this properly is to memcpy and pray that the compiler optimizes it away.

  • @BlackJar72
    @BlackJar72 6 ปีที่แล้ว +7

    I see a few very special uses, so I consider it very useful, though I first was introduced to the idea using unions.
    I often associate type punning with things like freelists, and have suspect its important for how some libraries get around endianess to use their own byte orders. I've also used like this to change a function for hash strings into one that hashes any data type (though preferable none that include pointers). Very useful, though definitely not something you just do everyday.

  • @bravet
    @bravet 4 ปีที่แล้ว +2

    This is awesome, more indept videos like this would be very nice! Good work!

  • @lukehanscom482
    @lukehanscom482 6 ปีที่แล้ว +2

    I would like to see some file input and output...great and thorough videos love to see more

  • @electrotsmishar
    @electrotsmishar 2 ปีที่แล้ว

    I think you will like Typescript. It's amazing

  • @b4ttlemast0r
    @b4ttlemast0r 10 หลายเดือนก่อน

    "//evil floating point bit hack
    //what the fuck??"

  • @zes3813
    @zes3813 3 ปีที่แล้ว

    wrgg, no such thing as reasonx or therex or not, doesn tmatter, do, say any nmw, only selfstx matrs

  • @GamersCreedTeam
    @GamersCreedTeam 6 ปีที่แล้ว +1

    For guys who are looking for a pun? 4:50 #DoublePointer

  • @haru02w89
    @haru02w89 ปีที่แล้ว

    I love having a type system, specially if you can change it along the way

  • @xtc564
    @xtc564 6 ปีที่แล้ว +1

    Hi! You could do a tut' about memory pools and create simple class for that. In the end you could give some advices to make a advanced pool or even make a new video about the advanced memory pool. I think, with your explanation we could go on a next level of efficient game programing.

  • @TrebleWing
    @TrebleWing 2 ปีที่แล้ว

    But.... like... the fast inverse square root tho.

  • @余淼-e8b
    @余淼-e8b ปีที่แล้ว

    Which IED do you use? It looks impressive.

  • @liorglass3850
    @liorglass3850 5 ปีที่แล้ว +1

    int and double are not promised to be address aligned, I think that punning double->int will always work but not the other way around

  • @Dienes
    @Dienes 3 ปีที่แล้ว

    Make sure to not break the strict aliasing rules when doing these things.

  • @nikoszervo
    @nikoszervo 6 ปีที่แล้ว +4

    Can you also make a video about the order you declare types inside a structure? I think the size of a struct is depended in the order you specify types because of something called Memory Alignment. Our professor mentioned it in the Assembly subject but i would like to hear it from you as well :p

  • @endrawes0
    @endrawes0 3 ปีที่แล้ว

    What's that thing you are doing with your arms at the opening?

  • @aurimas_8260
    @aurimas_8260 4 ปีที่แล้ว +1

    Not sure, but I think you could use UNION for same purpose, and avoid getting out of memmory range for a structure :?

    • @n0ame1u1
      @n0ame1u1 3 ปีที่แล้ว

      I think it's technically undefined behavior or something, but in practice yeah it does work like that on most compilers.