Search code examples
c++sdlsharedunions

Unions and sharing data fields(C++)


In the API documentation of SDL for the Union event it says that the the field type is shared among all the event(objects) in the union,how is this possible?

also for example this is perfectly legal

while(SDL_PollEvent(&event)){

  if(event.type == SDL_KEYDOWN){


   cout << "key down" << endl;
  }

and this is also works which logically makes more sense to me ,but I'm not sure how the first is even legal

    while(SDL_PollEvent(&event)){

   if(event.key.type == SDL_KEYDOWN){


       cout << "key down" << endl;
   }

Solution

  • A union has the potential to represent one out of multiple possible types/structures.

    union {
      int i;
      float f;
      char c;
    };
    

    In the example above, the memory which holds the union can represent an int or a float or a char. But it can only be one of those things; they are mututally exclusive. The union overlaps the underlying bytes used by each member in order to save space, and assumes you will know how to correctly interpret it.

    (Side note: to accommodate this, the 'size' of the union - the cloud of bytes in which the union is stored - must be large enough to hold the largest possible type defined in the union. In this case, int or float could each be 4 bytes, so the union will be at least 4 bytes.)

    One neat side-effect of this overlapping memory 'trick'; if a union describes multiple struct members, then they can share common fields.

    Example:

    union {
      struct {
        int type;
        int i;
      } OPTION_INT;
    
      struct {
        int type;
        float f;
      } OPTION_FLOAT;
    
      struct {
        int type;
        char c;
      } OPTION_CHAR;
    };
    

    Okay, neat; the union could represent any one of three possible structs. Notice, though; they all contain the exact same first member - type. Because of the way the memory is 'overlapped', the OPTION_INT type member shares the same memory as the OPTION_FLOAT and OPTION_CHAR type members. Thus, no matter which option is correct, the type member should always exist. This is possible because they all define the type field as the very first member.