When do I use a union in C or C++, instead of a struct?

Sdílet
Vložit
  • čas přidán 19. 06. 2024
  • Patreon ➤ / jacobsorber
    Courses ➤ jacobsorber.thinkific.com
    Website ➤ www.jacobsorber.com
    ---
    When do I use a union in C or C++, instead of a struct? // Unions are useful, but often overlooked in beginner classes, because we don't use them all that much, and because we can often get by without them. This video talks about unions, how they differ from structs, and when you might want to use a union in your C or C++ programs.
    ***
    Welcome! I post videos that help you learn to program and become a more confident software developer. I cover beginner-to-advanced systems topics ranging from network programming, threads, processes, operating systems, embedded systems and others. My goal is to help you get under-the-hood and better understand how computers work and how you can use them to become stronger students and more capable professional developers.
    About me: I'm a computer scientist, electrical engineer, researcher, and teacher. I specialize in embedded systems, mobile computing, sensor networks, and the Internet of Things. I teach systems and networking courses at Clemson University, where I also lead the PERSIST research lab.
    More about me and what I do:
    www.jacobsorber.com
    people.cs.clemson.edu/~jsorber/
    persist.cs.clemson.edu/
    To Support the Channel:
    + like, subscribe, spread the word
    + contribute via Patreon --- [ / jacobsorber ]
    Source code is also available to Patreon supporters. --- [jsorber-youtube-source.heroku...]

Komentáře • 213

  • @CraverYT
    @CraverYT Před 3 lety +115

    Unions are a case where I believe the verbosity of typing "union foo" (vs hiding behind a typedef) is a feature, not a bug.
    When you use a union, you are deliberately making the decision to refer to one memory location by multiple names. That's unusual enough that I want the "union" keyword front and center to draw a reader's attention.

    • @sagitswag1785
      @sagitswag1785 Před rokem +1

      This is good for more complicated unions, but probably not neccessary for the simple ones.

    • @vercolit
      @vercolit Před rokem +4

      I'm making a C api for a popular service and there are a lot of potential responses that all need a separate struct to retain the data. There are also many different enums, and removing all the typedefs for structs and enums significantly improved the readability of everything. I know it's a bit verbose, but for larger projects, I definitely recommend not typedeffing structs and unions

  • @lean.drocalil
    @lean.drocalil Před 2 lety +110

    I used unions in a Sega Master System emulator I'd started working on: the Zilog Z80 microprocessor has 8-bit registers that can pair up and act as though they were 16-bit ones. With the help of unions and structs, I could manipulate such registers both ways without the need for bitwise operations and further logic. Quite useful and clever 😁😁

  • @nonetrix3066
    @nonetrix3066 Před 2 lety +169

    In Soviet Russia we share the memory comrade no structs or classes allowed

    • @kemaruproduction
      @kemaruproduction Před 2 lety

      Soviets have collapsed, now the world is doing it the USA way.

    • @pxolqopt3597
      @pxolqopt3597 Před rokem

      A perfect communist utopia shouldn't have any classes

    • @nickgennady
      @nickgennady Před rokem +1

      But structs are data. At least in C.

    • @aryanverma6261
      @aryanverma6261 Před rokem +18

      Missed opportunity to call it Soviet Union

    • @bachden_se
      @bachden_se Před rokem +2

      Great Soviet, long live Soviet!

  • @DrSTAHP
    @DrSTAHP Před 3 lety +35

    I love how whenever I stumble across a question about C/C++ essentials, you're posting a video about that exact thing.

    • @JacobSorber
      @JacobSorber  Před 3 lety +8

      Yeah, inter-language bindings has been on my topic list for a while. Just need to get around to making the videos. 😀

    • @ramakrishna4092
      @ramakrishna4092 Před rokem +1

      @@JacobSorber hello sir your way of explanation is better than paid classes and I am really sorry to compare with them ..
      I had a small doubt in union topic when I execute the below code
      #include
      #include
      #pragma pack(1)
      typedef union
      {
      uint32_t* p;
      uint8_t* q;
      } somepointer;
      int main(int argc, char** argv)
      {
      uint32_t r;
      uint8_t s;
      somepointer p;
      r = 10; s = 15;
      p.p = &r;
      p.q = &s;
      printf("%d %d
      ", *p.p, *(p.q));
      }
      I am getting answer 2575 15 but i expected both 15 as output what is difference when we use pointer member in union how the memory is handled .

    • @postalci95
      @postalci95 Před 9 měsíci

      union members p and q only store the memory location of a pointer that is just 4 bytes. In your main program you set the p field of the somepointer and then you set the q field of the somepointer that overrides the memory location in p field since p and q use the same memory location. That's why you got different result from p location. @@ramakrishna4092

    • @donuts6230
      @donuts6230 Před 8 měsíci

      @@ramakrishna4092 this is because now you have the pointer to s into the union somepointer, and s points to a single byte. When you dereference p.p, you are dereferencing a pointer to a FOUR byte type, so the cpu fetches not only the single byte that the pointer in somepointer is pointing to, but also the next three bytes after wherever s is in the stack, thus returning a non-sensical value.

  • @Reiqy
    @Reiqy Před 3 lety +51

    Unions are awesome when you're making a programming language with dynamically typed variables. It's nice to have a struct with the value type information and an union storing the actual value.

    • @victorscarpes
      @victorscarpes Před rokem +2

      I'm working on a university project to make a python assembler in C. The teachers invented a .pys filetype that works as a middle step between .py and .pyc and we are programming the assembler that converts .pys in .pyc in C. We use unions exactly for what you've described.

    • @sharkie115
      @sharkie115 Před 7 měsíci

      AFAIR it's done exactly this way in PHP. It's internally called zvalue.

  • @matthewkott8863
    @matthewkott8863 Před 3 lety +11

    Thanks for this. One of the C books from back in the day (©1988) concluded a very short chapter introducing unions with the unhelpful statement: "The author hasn't yet found a reason for using union structures [sic] instead of solving the problem with other C data types."

  • @EdwinFairchild
    @EdwinFairchild Před 2 lety +24

    a neat thing about unions is you can use them to serialize a float to send it down some serial communication like uart , a float element and an uin32_t element and thats it. then send the uint32_t byte by byte and assemble on the other end back to a float, via pointer or another of the same union. serializaton like this is also useful with structs to send them along their serial way, you don't need a union to do that but it's a much cleaner way than with pointers

    • @Minty_Meeo
      @Minty_Meeo Před rokem

      iirc there's some dumb obscurities in the language that says type-punning with unions is implementation-defined behavior or something like that. The most correct way is to use memcpy to bit-cast (the compiler is smart enough to optimize it) or, assuming your compiler supports it, use __builtin_bit_cast / std::bit_cast.

  • @xeridea
    @xeridea Před 2 lety +15

    Unions seem like one of those things that aren't generally useful, and very error prone, but would have some very good niche cases. Could be useful for something like fast inverse square root, or some case where type punning is useful. Coming from C++, polymorphism would be a lot less error prone I would think for the use case shown here though.

  • @RajeshKulkarni26
    @RajeshKulkarni26 Před 2 lety +12

    I usually use a union for a UART receive buffer . Then you can use the data type as a uint8_t or a “char” which also uses 8 bits .

  • @martandrmc
    @martandrmc Před 3 lety +19

    I have been waiting for this video. Thanks for talking about unions.
    You are my top source of C lessons. Thank you for your efforts.

    • @JacobSorber
      @JacobSorber  Před 3 lety +10

      Yeah, I knew a few of you were waiting for it. Glad I could help.

  • @abxxyz6569
    @abxxyz6569 Před 2 lety +1

    I absolutely love how you explain all the concepts with a little hands-on video of their implementations.

  • @mlogsdon1740
    @mlogsdon1740 Před 2 lety +4

    I have been using Linux for over 15 years and struggling to learn C on my own by reading manpages and trying to decipher source code. I have learned more in a few hours on your channel than all those years combined. Thank you for what you do.

  • @PerchEagle
    @PerchEagle Před 2 lety +1

    Very informative and excellent example.
    I really got a more profound understanding that some tools aren't supposed to work very efficiently out of the box but rather it give higher advantages when used in combination with other stuff; like, structs in this example.

  • @skan8494
    @skan8494 Před 3 lety +20

    I searched for ages to find a tutorial to know how to use it, and when i saw this ... i was in paradice

  • @LorenHelgeson
    @LorenHelgeson Před rokem +1

    Thanks. Explained it well enough for me. Going over structs in a course right now, and the instructor just flat-out says "don't use unions. They are dangerous." What you gave is a perfect use case of when I should consider them.
    As with all things low-level programming, they are only dangerous in the hands of a rookie, but powerful in the hands of someone who knows what they are doing. Much appreciated.

  • @user-oc2fh5hw8t
    @user-oc2fh5hw8t Před rokem

    the example was amazing, thank you!

  • @akhileshb_
    @akhileshb_ Před 2 lety

    Very nicely explained professor, thanks a lot!

  • @Psykorr
    @Psykorr Před 2 lety +3

    Very useful with matrices and vectors. Have a union with an anonymous struct inside holding the individual elements, and an array with the size of the number of elements in the top level union. Then you can change/get the values of the elements by their names (like x, y, z etc) or iterate over them using the array.

  • @TheLonelyLPer
    @TheLonelyLPer Před 2 lety +15

    This channel is a literal goldmine for someone learning C and C++. Thank you so much!!

    • @xeridea
      @xeridea Před 2 lety +1

      czcams.com/play/PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb.html

    • @TheLonelyLPer
      @TheLonelyLPer Před 2 lety +2

      @@xeridea you are a god send!!! I needed this since my programs difficulty curve just shot into space! Thank you so much man!!!!

  • @billbez7465
    @billbez7465 Před 3 lety

    Very understandable and useful. Thanks!

  • @greendog105
    @greendog105 Před rokem

    awesome explanation, thanks!

  • @stephanrotolante7370
    @stephanrotolante7370 Před 3 lety

    I love your channel dude, keep it up!!

  • @undertaker901
    @undertaker901 Před 10 měsíci

    You explained a lot about the advantage of saving memory, but glossed over the fact that you can stomp on values already saved. Would like to know more about the cons/pitfalls when using these.

  • @coolbrotherf127
    @coolbrotherf127 Před 2 lety

    I've been programming C++ for like 3 years now and this is the clearest way someone has explained this. Most people just handwave the question and just say it's "some old thing from C, don't worry about it."

  • @jonbezeau3124
    @jonbezeau3124 Před rokem

    I use unions to get at byte values for floating point numbers for rounding, un-signing, etc.
    Also the different values in a union can themselves be structs which makes for some pretty powerful either/or representations.

  • @johntoe6127
    @johntoe6127 Před 3 lety +1

    I've used unions a lot. Any time you have a record format with a variable area, you can union together several structs to define the area.
    You can also union a struct with a buffer. Read the record into the buffer name, and refer to all the fields by the struct names.

    • @iPhoneApple4S
      @iPhoneApple4S Před 2 lety

      Hey, do you mind posting any examples in code for those mentioned applications?

  • @Uerdue
    @Uerdue Před 2 lety +2

    I recently wrote a (pretty bad :D) JSON parser as a training exercise and was wondering how to best implement the dynamic typing... Ended up just using void pointers and lots of casting... Looks like unions would've been the proper way to do it. Good to know!

  • @protonmaster76
    @protonmaster76 Před 5 měsíci

    I've not seen an unnamed union in a struct before. Nice trick.
    Also unions can be used to serialized a struct, which is handy on a micro pricespy when sending data over a serial link.

  • @ohwow2074
    @ohwow2074 Před 2 lety

    The final example was brilliant.
    And yes I'm a huge Star Wars fan!

  • @framepointer
    @framepointer Před 3 lety +2

    thank you for making a video on this, youve seen my comment!
    edit: btw, shouldnt we use the %zu format specifier when printing a size_t?

  • @gregoryfenn1462
    @gregoryfenn1462 Před 11 měsíci

    Bold of you to discuss unions without mentioning hardware peripherals where the same configuration space will have different register meanings depending on the version or mode of the peripheral being configured. That's like 95% of the usage for unions.

  • @90_98
    @90_98 Před 5 měsíci

    I use unions to reinterpret data from different types, or extract individual bytes from an integer, or combine multiple bytes into an integer, etc.

  • @marusdod3685
    @marusdod3685 Před 3 lety +9

    C unions are very powerful, they basically allow you to implement pattern matching and inheritance without advanced language constructs

    • @zeinfeimrelduulthaarn7028
      @zeinfeimrelduulthaarn7028 Před 3 lety

      How

    • @marusdod3685
      @marusdod3685 Před 3 lety +2

      @@zeinfeimrelduulthaarn7028 look it up

    • @zeinfeimrelduulthaarn7028
      @zeinfeimrelduulthaarn7028 Před 3 lety +3

      @@marusdod3685 yes sorry that was a stupid question aha, ty for answering, i'd have ignored myself if i were you

    • @henrykkaufman1488
      @henrykkaufman1488 Před 2 lety

      have union and enum in a struct. use enum to indicate which variable of union is valid. use switch to do operations on a struct depending on what you need. Simpler than OO, right?

  • @Tupiniviking_de_osasco
    @Tupiniviking_de_osasco Před 3 lety +1

    You have such a good way to teach... Do you intend to release any course or something? It would be amazing

    • @JacobSorber
      @JacobSorber  Před 3 lety +2

      Thanks. Short answer. Yes, probably...stay tuned...just too busy for my own good, sometimes.

  • @imad9948
    @imad9948 Před 3 lety

    thanks so much, Jacob

  • @RAINE____
    @RAINE____ Před 3 lety

    Another lovely video

  • @KangJangkrik
    @KangJangkrik Před 2 lety +3

    Union is very useful for networking, because sometimes we expect structured data (struct) but has to be bytes before being sent. Thus, it would be struct in an union.

  • @willwatson4134
    @willwatson4134 Před 2 měsíci

    Thank you this finally clicked for me!!

  • @edgarbonet1
    @edgarbonet1 Před 2 lety

    I use something like this for handling the registers of an embedded device:
    struct {
    // stuff...
    union {
    struct {
    uint16_t foo;
    uint16_t bar;
    uint16_t baz;
    // etc...
    };
    uint16_t regs[REGISTER_COUNT];
    };
    } the_device;
    The communication protocol requires the registers to be identified by numbers (hence the array), but the source code is more readable if I can write
    the_device.foo
    rather than
    the_device.regs[INDEX_OF_FOO]

  • @karmavil4034
    @karmavil4034 Před rokem

    Oh lord. I've declared a union and it worked. Nice! I'm gonna be breaking my compiler mixing them with templates :)

  • @matanpazi3777
    @matanpazi3777 Před rokem

    Thanks for the video!
    Like some people mentioned in the comments, another use case that arose from this shared memory feature is data packing/unpacking in serial communication.
    I found a technical article that summarizes it nicely:
    "Union in C Language for Packing and Unpacking Data" - by Dr. Steve Arar

  • @ryonagana
    @ryonagana Před 3 lety

    i used union once when i had to read a CFG file that can store a flag, string or float
    its the easiest way to read the once then convert later

  • @hirokjyotinath2246
    @hirokjyotinath2246 Před 3 lety

    Your are great please make more video lectures

  • @rustycherkas8229
    @rustycherkas8229 Před 2 lety

    Writing my own Base64 conversion function was a great place to trot out a union.
    The 24 bits of binary expand into 32 bits of printable ASCII, and vice versa...
    You gotta be a bit careful about 'endian', but it's a clean solution lacking the usual plethora of 'temp' variables. and oddball loops...
    And, on my 32-bit system (for my own use), I sometimes make a union of a (native) double with 2 ints or a pointer and an int, or whatever, allowing functions to return multiple values melded into a single package. Yes, it's a non-portable hack, and one needs to be careful, but it partially overcomes C's aversion to passing structs...

  • @query4aman
    @query4aman Před 3 lety +1

    First comment 😊
    Thanks for this video...I was hoping to see this discussion... thanks!😊

  • @AdrianBan04
    @AdrianBan04 Před 2 lety

    I'm using those unions when I'm working in embedded systems and, for example, I need to transmit an uint64_t variable via infrared LED to an A/C. But this uint64_t contains multiple commands and parameters inside. With union you can use only one uint64_t space memory and divide it in multiple uint8_t, uint16_t, uint32_t variables or even define number of bits for each member inside of this variable. Each member it is a command or a parameter for A/C.
    Actually you are sending a set of: mode, temperature, fan speed, etc in one uint64_t variable.

    • @ajinkyakamat7053
      @ajinkyakamat7053 Před 2 lety

      I have used unions like for this in the past. Infact major vendors like Texas instruments use this technique in the hardware abstraction library. But using this in the networking stack is a bad idea. This technique relies on implementation defined behavior which makes your code less portable. Depending on your business priorities, it might be ok. But in the long run, it causes huge issues. On of my previous codebases made heavy use of this technique. Due to cost and availability issues, we had to change our microcontroller and we ended up having to rewrite most of our firmware.

  • @UnknownSENKu
    @UnknownSENKu Před rokem

    Thanks

  • @AlyxCouch
    @AlyxCouch Před 2 lety +1

    Hi Jacob, great video. If you are looking for video suggestions, one I'd be interested in is why there seems to be such a holy war between using typedef and not using it. It seems like half the people I ask are vehemently against them, and the other half use them all the time. I'm not totally sure I understand the reason against. Thanks

    • @JacobSorber
      @JacobSorber  Před 2 lety +2

      Thanks. I'll see what I can do. The argument is generally about type obfuscation.

  • @andrewporter1868
    @andrewporter1868 Před rokem

    I only learned recently the hard way and very quickly that using a union is the equivalent of typecasting the variable, not the literal being assigned to it, i.e., ((type) variable) = value, not variable = (type) value. The reason I found out was because I was writing as uint32_t and then reading as uint64_t. In debug, I noticed the low 32 bits had the correct value, but not the high 32 bits. Sure enough, it turns out I had mistakenly believed when I first was introduced to C that it had the same behavior as casting the assignment value. This differs in that, at least for x86, casting a uin32_t to uint64_t would generate a movzx (move with zero extend) instruction, whereas with a union instead, we just get a movd instruction (move dword).
    It was for creating a simple output parameter that gives two status codes: general_cause, and specific_cause. This would permit the user of the procedure to determine what should be done with the output based on the status codes given, in this case, for an HTTP API that I implemented using WinHTTP. The solution was to set the values to zero at the start of each procedure that provides these output parameters.
    Certainly an improvement over exceptions to use this simple method, but unfortunately, C doesn't have a nice way of clearly separating input parameters from output parameters, and polluting the return values with interprocedure state metadata is absolutely unacceptable as the return value should return the result of its execution--things that are inherently void type shouldn't return a bool or otherwise for information about operation success or failure because that is accidental to the procedure and makes the procedure interface ambiguous in the best case, and misleading in the worst case. It's incredibly cringe to see if (!WinHttpProcedureThatReturnsNothing(...)) { fatalf(...); } as opposed to WinHttpProcedure(..., &status); if (status.general_cause == HTTP_FAILURE) { fatalf(...); }.

  • @gabriel-ab
    @gabriel-ab Před 3 lety +2

    Finally a useful example of unions, you are the best! Thanks for all these videos.

  • @Trezker
    @Trezker Před rokem

    Just realized I could use this in project. I had a Header struct and two different node structs that had the header as the first member plus different data arrays that occupy the same space. Now I unioned the data arrays and no longer have to access the header members through object->header.member. One little issue is that I need to know the size of the header to determine how big the data arrays can be and I'm not sure of the best way to do that... I want the struct to always be one memory page in size.

  • @Astfresser
    @Astfresser Před 2 lety

    Could you maybe avoid endianness issues by template specialization? Is there a predefined trait for this?

  • @NoName-md6fd
    @NoName-md6fd Před měsícem

    Total newb, but I know what unions are for and it honestly blows my mind how clever it is. The common understanding I have seen in videos is that saves memory, but you can also intentionally do variable shadowing or have a variable "interpreted as" another type.

  • @michaelkotthaus7120
    @michaelkotthaus7120 Před 3 lety

    The required C MISRA rule 18.4 from 2004 says that unions shall not be used. MISRA C++ 2008 says the same in rule 9-5-1.
    In the edition MISRA C edition from 2012 this rule is lowered from "required" to "advisory" (19.2).
    Personally, I also try to avoid unions. But there are some situations where a union is the only or the best way. Some examples are shown in the comments.
    For your example, Jacob, a C++ programmer would advice to use polymorphic classes. In C, I could imagine to use a struct with pointers to the specific data (personality, firmware). Only one of these pointers should be unequal to NULL. With this, you can also save the boolean flag which distinguishes between robot and human being.
    Nevertheless: This is again a great eposiode which helps me to think about data concepts. Thank you!

  • @cameronball3998
    @cameronball3998 Před 2 lety

    It feels like conceptually we could replace the idea of a struct with an interface like in Java or a protocol in Swift, or in some other way via subclasses. Obviously the point of C is to not have classes, but still, just a thought.

  • @neerajkale
    @neerajkale Před 3 lety

    A small note on how the endianness of CPU affects the alignment of elements in the union would be helpful. I believe you might have already covered it in one of the videos, but would be useful here for someone new, since we are already in this context.
    FYI, my previous organization's 20+ year old firmware (still evolving) has this common datatype which consists of a structure of union of all datatypes like int, bool, float, string, etc in it. The variable of this complex datatype is thrown around everywhere in a highly complex-interdependent environment, over network and across various platforms, which seems very complex at first but is a lifesaver once you understand it. The actual datatype of this variable, and the value it holds is evaluated only at the source and the intended destination. I think it's like a simple encapsulation.

    • @Astfresser
      @Astfresser Před 2 lety

      That sounds interesting can you talk more about it?

  • @adjmonkey
    @adjmonkey Před 3 lety +2

    Thanks for the video. Throughout my CS degree, unions were kinda skipped over lol, so I had no idea the difference. Only question I have is how it determines which is bigger when given pointers? Does it assume 4 bytes for the pointer or follow the address and use sizeof() internally?

    • @R4ngeR4pidz
      @R4ngeR4pidz Před 3 lety

      Pointers are always 8 bytes, `sizeof(char*)` == `sizeof(void*)` == `sizeof(struct very_long_struct*)` :)

    • @JacobSorber
      @JacobSorber  Před 3 lety +2

      Pointer size varies by machine. Some microcontrollers have 2-byte or 4-byte pointers. Your typical 64-bit machines (my laptop and probably yours) have 8-byte (64-bit) pointers. And, yes, on a particular machine, the size of a pointer is the same no matter what it points to.

  • @gpcm
    @gpcm Před 2 lety

    I use union in 16-bit mcu when I need to read the MSB or the LSB separately. I just think it is more readable than doing pointer arithmetic:
    typedef union {
    int word;
    char byte[2];
    } data16_t;

  • @Ilyas_Alrai
    @Ilyas_Alrai Před 3 lety

    Can you give us some projects to work on to go advanced with c ?

  • @_slier
    @_slier Před rokem

    union can be use for type punning and polymorphism

  • @Tyler_0_
    @Tyler_0_ Před rokem

    @8:37 Shouldn't line 30 be "c.firmware_version" rather then "c->firmware_version" since it is an int and not int* ?

  • @sukivirus
    @sukivirus Před 3 lety +2

    Unions are so useful. Its the basic for inheritance. I use it all the time. :)

    • @sukivirus
      @sukivirus Před 3 lety +3

      I just wrote a program in notepad and have not tested it but you will understand the basic of what I am trying to do. enum TYPE
      {
      RECT, CIR
      };
      // Child Struture - 1
      struct Rectangle
      {
      // Width & Depth
      float b,d;
      };
      // Child Structure - 2
      struct Circle
      {
      // Radius
      float r;
      }
      // Parent Structure
      struct Shape
      {
      union
      {
      struct Rectangle R;
      struct Circle C;
      }
      enum TYPE type;
      };
      // Function to calculate Area
      float calculate_area(Struct Shape s)
      {
      if (type == RECT)
      return s.R.b * s.R.d;
      else
      return 3.14 * s.R.r * s.R.r;
      }
      int main()
      {
      struct Shape shp;
      shp.type = RECT;
      shp.R.b = 10; shp.R.d = 20;
      printf("Area = %f
      ", calculate_area(shp));
      }

    • @R4ngeR4pidz
      @R4ngeR4pidz Před 3 lety +2

      @@sukivirus Looks great, any reason you have comments littered throughout instead of naming the variables that way?

    • @sukivirus
      @sukivirus Před 3 lety

      @@R4ngeR4pidz I agree my bad

    • @267praveen
      @267praveen Před 3 lety

      Won't virtual functions be much clearer for achieving this instead of unions?
      With this approach you need to specify 'type' at compile time only.

    • @w.mcnamara
      @w.mcnamara Před 2 lety

      @@267praveen C doesnt have virtual functions. If you were talking abt cpp you may aswell just use the oop features for this case anyway…

  • @kylefan8478
    @kylefan8478 Před 2 lety

    Is your example a typical use case of unions? why not use class inheritance to specialize instead?

  • @hansdietrich83
    @hansdietrich83 Před 3 lety

    Could you use this to store a large datapacket and acessing each byte seperatly? Something like this:
    union{
    uint32_t data;
    struct{
    char 1;
    char 2;
    char 3;
    char 4;
    }
    }

    • @JacobSorber
      @JacobSorber  Před 3 lety

      Yes, sort-of. You can easily run into endianness issues if you're not careful, and make sure you pack the struct to keep your compiler from inserting padding between the members. But, otherwise, yes this will work.

  • @267praveen
    @267praveen Před 3 lety +2

    Thanks.
    In Summary - Unions help to save space.

  • @cleightthejw2202
    @cleightthejw2202 Před 3 lety

    I have a question :)
    What is the difference/similarity between a struct in C versus a hash-table or maybe even 'object'??
    I'm more of a 'head learning' place rathe rthan actually programming. From what I have in my head is that the struct may be like a hash-table or object from a language like C compared to C++ or using a scripting language like PowerShell in Windows
    Thank you

    • @Spielix
      @Spielix Před 3 lety +1

      A struct is like a class (object) without methods (member functions in C++ lingo) . In C++ struct and class are almost the same. In a hash table lookup is happening at runtime, while for a struct the compiler knows exactly which member variable is located where in memory. You certainly can use structs to build a hash table.

  • @thethiny
    @thethiny Před 2 lety

    I don't understand why you wrote "typedef" for the struct. Whenever I address a struct I instantiate using its name. Example:
    struct foo {
    int x;
    };
    I would just use:
    foo myFoo;
    And go on with my day and it works fine. I never had to write "struct foo myFoo;". Care to explain?

  • @Felipe-Felisberto
    @Felipe-Felisberto Před 5 měsíci

    Anyone could tell me why the size of the struct is 12 bytes, when: int = 4 bytes, float = 4 bytes and char = 1 byte? The other 3 bytes are used for what?

  • @ZachBradyisBrachZady
    @ZachBradyisBrachZady Před 2 lety

    One thing I am confused by is what is the difference between accessing a struct property via -> vs dot notation? I've Googled a bit on this and it seems like they are not exactly interchangeable depending on whether or not the property is a true pointer.

    • @edgarbonet1
      @edgarbonet1 Před 2 lety

      You use “->” when you have a pointer: it's either
      a_struct.a_member
      or
      a_pointer_to_struct->a_member
      The later is just syntactic sugar for
      (*a_pointer_to_struct).a_member

  • @johnconnery7547
    @johnconnery7547 Před 3 lety

    It's pretty useful when writing a gameboy emulator because each of the cpu's register can eitther be treated as 1 16-bit reg or 2 8-bit registers.

    • @SerBallister
      @SerBallister Před 2 lety

      I wanted to say the same. You can also mix bitfields in with it too (perfect for HW registers), so you have nice setter/getters for the fields while also able to read/write the whole 16/8bit value at once. Makes code a lot easier to read too.

  • @milo20060
    @milo20060 Před rokem

    Ok so unions are basically if there is a time where only one variable is true out of many then unions are pretty good to use as optimize the code more ^^

  • @sharpfang
    @sharpfang Před rokem

    IMO the unions rule when you handle some control protocol. You have two dozen different commands each with different parameters, so you make a struct command, union parameters, to pass the command around.

  • @jenselstner5527
    @jenselstner5527 Před 3 lety

    I use a union, when my program has to convert e.g. 4 char into an int32_t (maybe an ipv4 address), which make it very easy without a bunch of bit fiddling. ;o)
    Another good reason, if you need a kind of variant variable type.

    • @267praveen
      @267praveen Před 3 lety

      Please share a code example as it's seems interesting case

    • @jenselstner5527
      @jenselstner5527 Před 3 lety

      @@267praveen
      This is a generic 4 bytes to int converter
      #include // To get __LITTLE_ENDIAN
      #include // For uint8_t, etc. typedefs
      // toInt() bytes to int converter.
      typedef union u_char2Int{
      char ac4Bytes[4];
      uint32_t uint32;
      } t_char2Int;
      /*******************************************************************************
      * Name: toInt
      * Purpose: Converts up to 4 bytes to integer.
      *******************************************************************************/
      int toInt(char* pc4Bytes, int iCount) {
      t_char2Int tInt = {0};
      for (int i = 0; i < iCount; ++i)
      # if __BYTE_ORDER == __LITTLE_ENDIAN
      tInt.ac4Bytes[i] = pc4Bytes[i];
      # else
      tInt.ac4Bytes[i] = pc4Bytes[iCount - i - 1];
      # endif
      return tInt.uint32;
      }

  • @deniskozmin4207
    @deniskozmin4207 Před 2 lety

    Where can I see the content of Makefile?

  • @fders938
    @fders938 Před 2 lety

    I've used unions so I could do floating-point bithacks relatively easily

  • @sababugs1125
    @sababugs1125 Před 3 lety

    If an union has multiple pointers and then we modify the Union will and use those pointers will that cause a segmentation fault

    • @JacobSorber
      @JacobSorber  Před 3 lety +2

      Maybe, maybe not. It depends on what you're doing with those pointers, but the pointers will share the same location, so writing to one and then the second write will overwrite the second. So, if you access the first, you'll get the value you stored for the second. If that first pointer was important, you might have lost important data (and possible memory leak?). But, whether or not it seg faults, depends on what address you stored for the second one, and what you try to do with it.

    • @brucelytle1144
      @brucelytle1144 Před rokem

      @@JacobSorber I haven't actually programmed for 20 years or so, I used unions for the flexibility they give you. I was under the impression that although the pointer is concerned, it is the same, the compiler interpretation of it varies in the manner (variable) used in the source code.
      Is this behavior still correct?

  • @JfhuTheJedi
    @JfhuTheJedi Před 2 lety

    Where have you been my whole undergrad C programming life????

  • @skaterfabi11
    @skaterfabi11 Před 2 lety

    way to less views for so good content!

  • @primevst
    @primevst Před 7 měsíci

    Haven't really watched the video yet, but be careful that in c++ ( don't know about c ) a lot of the ways you use a union is UB.
    When you assign a value to one of its fields, you should only use that field.

  • @Beatleman91
    @Beatleman91 Před 2 lety

    Not that I have a lot of experience but I am yet to see production code that uses unions.
    And that example shows once again why one should switch to C++: Just have a factory class Character with two children Person and Robot.

  • @user-to1lb6dj6g
    @user-to1lb6dj6g Před 2 lety +1

    #define struct union

  • @unperrier5998
    @unperrier5998 Před 2 lety

    a better use case for unions imho is network programming.

  • @VIVEKSHARMA-zx6uc
    @VIVEKSHARMA-zx6uc Před 3 lety

    main()
    {
    char *p = 's';
    printf("%s",p);
    }
    It's printing nothing.
    As soon I changes format specifier to %c. It works.
    Can anyone tell me the logic behind this.

    • @JacobSorber
      @JacobSorber  Před 3 lety +1

      's' is a char (a usually 1-byte integer). "s" is a char* (contains the address of a block of memory containing the 's' character followed by a null character. You're assigning p (a pointer) to be that integer value (rather than an address). With "%c", you're telling printf to interpret p as a character. So, the code is odd, but things do work, because both lines are forcing p to be used as a char. With %s, you're telling printf to treat it like a pointer to some characters, and since you didn't set up p that way, you could get a number of different outcomes (most likely no output, garbage, or a seg fault), depending on what is stored at address 115.

    • @VIVEKSHARMA-zx6uc
      @VIVEKSHARMA-zx6uc Před 3 lety +1

      @@JacobSorber Thanks a Ton..

  • @miladbannourah7798
    @miladbannourah7798 Před 2 lety

    I'm starting my computer science major next month, we are gonna be best friends buddy

    • @JacobSorber
      @JacobSorber  Před 2 lety

      Alright. Let's do this. 😀
      Best of luck.

  • @Eviatarm
    @Eviatarm Před 3 lety

    I personally against union, they're fun and powerful but their downside is that the system endianness also matters, meaning that little and big endian would produce different results.
    If possible, I'd always prefer bitwise operations over union, and in C++ std::variant also may come handy rather than using union and a type.

    • @SimGunther
      @SimGunther Před 3 lety

      Structs vs C++ tuples?
      My preference is structs/classes (if necessary) by default as tuples make for a weird mess if not used properly in addition to a bunch of templating madness.

    • @Eviatarm
      @Eviatarm Před 3 lety

      @@SimGunther If possible I'd always pick structs/classes, and in many cases structs/classes are actually faster than tuples.

    • @cigmorfil4101
      @cigmorfil4101 Před 2 lety

      I can see endianness only matters when using a union for things like joining smaller registers into a larger register, eg
      union reg_pair
      {
      struct
      {
      int_8 b,c;
      }
      int_16 bc
      };
      } mypair;
      on a little endian system this would swap the two 8 bit registers being used together, but not on a big endian system.
      If you're using the union to merge different data together then endianness isn't going to matter. I used a union to merge the different data-section types in a file: each record was the same length but depending upon a record header the actual data stored differed: read record, check header of record and access the data as appropriately.

  • @SriHarshaChilakapati
    @SriHarshaChilakapati Před 3 lety +1

    In this case, an alternative would be to use a void pointer as void* versionOrPersonality. Cast it to the correct type if the isRobot flag is set to true. I recall that we were taught to almost never use unions as in today's scenario, they are considered bad code. A place where I've seen it is to extract bits from a number.

  • @vladrootgmailcom
    @vladrootgmailcom Před 3 lety

    Hi, thanks. So basically the memory for the "char *personality" is allocated/deallocated automatically?

    • @cigmorfil4101
      @cigmorfil4101 Před 2 lety

      No.
      In the code given when the char "personality" of hanssolo is assigned it is assigned[1] as a pointer to the constant string (and the version_type contains this address as an int), but the char "personality" of r2d2 contains the value 42 - a very likely segmentation fault if tried to be accessed)
      [1] at least it was when I did most of my C programming back in the '80s and '90s.

  • @datawolk
    @datawolk Před 2 lety +1

    Why is it not necessary to malloc the char* pointer?

    • @edgarbonet1
      @edgarbonet1 Před 2 lety

      Because string literals are statically allocated.

    • @cigmorfil4101
      @cigmorfil4101 Před 2 lety

      And it is set to point to the start of the constant string.

  • @lordangus77
    @lordangus77 Před 3 lety +7

    Would be awesome to watch you code in Rust, just saying haha

    • @Hellohiq10
      @Hellohiq10 Před 3 lety +5

      Nah

    • @parlor3115
      @parlor3115 Před 3 lety

      @@Hellohiq10 Yah...Rust is the future bruh

    • @Hellohiq10
      @Hellohiq10 Před 3 lety

      @@parlor3115 maybe for c++

    • @267praveen
      @267praveen Před 3 lety

      Good PJ.. hahaha.

    • @parlor3115
      @parlor3115 Před 3 lety

      @@Hellohiq10 Even for c. There's a project where an OS is being built with rust so the language is pretty capable. Plus, it's time to have a modern language for embedded systems. C is ancient and should just die.

  • @blitvar1
    @blitvar1 Před 3 lety +1

    Can you make a union of structs?

  • @nichtleo8505
    @nichtleo8505 Před 3 lety

    I often use unions.

  • @GCAGATGAGTTAGCAAGA
    @GCAGATGAGTTAGCAAGA Před měsícem

    What's the difference between union and a struct? Structs don't stage walkouts 🙂🙃🙂🙃

  • @antonw8134
    @antonw8134 Před 3 lety

    No mention of tagged unions? en.m.wikipedia.org/wiki/Tagged_union

    • @homelikebrick42
      @homelikebrick42 Před 3 lety +1

      What he showed in the video is basically a tagged union

    • @antonw8134
      @antonw8134 Před 3 lety

      @@homelikebrick42 That's my point exactly! Names are hard, but without using a name for the functionality being demonstrated makes it difficult to remember the concept (for people like me at least :^). Categorization is important.

    • @JacobSorber
      @JacobSorber  Před 3 lety

      Thanks for filling in the gaps in what I said (and didn't say).

  • @cepson
    @cepson Před 2 lety

    Han Solo is not a robot, but Rick Deckard is.

  • @LoesserOf2Evils
    @LoesserOf2Evils Před 3 lety

    C unions remind me of Pascal unions.

  • @TheVralapa
    @TheVralapa Před 3 lety +4

    std::variant is preferred in c++.

    • @Psykorr
      @Psykorr Před 3 lety

      I googled that thing.. It is really ugly imo. I prefer union even in c++ i do not like that dogmatic notion that in some language it is prefered to use some lib-feature just because some guy invented it. Of course the author of std::variant recommends it, they want people to use it so that they feel that they did not waste their time making that thing up. No offence it is only personal opinion, you should use it if you want to :)

    • @TheVralapa
      @TheVralapa Před 3 lety +1

      @@Psykorr of cource. You're welcome to use whatever you like. The core guidelines/best practices still recommends std::variant.

    • @dmitripogosian5084
      @dmitripogosian5084 Před rokem

      Which uses union inside in the standard implementation

    • @TheVralapa
      @TheVralapa Před rokem

      @@dmitripogosian5084 yes, but it's a lot harder to misuse

    • @dmitripogosian5084
      @dmitripogosian5084 Před rokem

      @@TheVralapa The point is, if you are interested how things work in C++, you need to find out what is union. If you are not interested, sure, you may skip whatever you want to skip.

  • @cuteisjustice8208
    @cuteisjustice8208 Před 3 lety +1

    I thought you are gonna write "bool ismale" lol.

  • @peregrin71
    @peregrin71 Před 7 měsíci

    In C++ you don't... you use std::variant. (unions in C++ just have to many corner cases with undefined behavior). So it is better to limit your explanation to "C" only

  • @yihan4835
    @yihan4835 Před 2 lety +1

    Use std::variant instead.

  • @thomas_m3092
    @thomas_m3092 Před 2 lety +2

    unions should not be used in C++. There is a safer and better option in std::variant.

    • @robertkiestov3734
      @robertkiestov3734 Před 2 lety

      Don’t use anything from the C++ standard library if you don’t hate yourself. C-styled C++ is the way to go.

    • @thomas_m3092
      @thomas_m3092 Před 2 lety

      @@robertkiestov3734 Why use C++ at all then ?

    • @robertkiestov3734
      @robertkiestov3734 Před 2 lety

      @@thomas_m3092 Classes and function overloading, that’s pretty much it.

    • @w.mcnamara
      @w.mcnamara Před 2 lety +1

      @@robertkiestov3734 this is horrible advice

    • @robertkiestov3734
      @robertkiestov3734 Před 2 lety

      @@w.mcnamara Maybe Rust is the language for you then, axewound. You will never be a woman.