Thread: How does this work?

  1. #1
    Registered User
    Join Date
    Mar 2009
    Posts
    399

    How does this work?

    Code:
    typedef union{
      Uint8 type;
      SDL_ActiveEvent active;
      SDL_KeyboardEvent key;
      SDL_MouseMotionEvent motion;
      SDL_MouseButtonEvent button;
      SDL_JoyAxisEvent jaxis;
      SDL_JoyBallEvent jball;
      SDL_JoyHatEvent jhat;
      SDL_JoyButtonEvent jbutton;
      SDL_ResizeEvent resize;
      SDL_ExposeEvent expose;
      SDL_QuitEvent quit;
      SDL_UserEvent user;
      SDL_SysWMEvent syswm;
    } SDL_Event;
    SDL's implementation of this union allows you to always access the type member to see what type of event is stored. But how exactly do SDL manage to store two types at the same time in a union without corrupting either, and doing so in a portable manner as well?

  2. #2
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    You should start answering this by reading on what unions are.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    The LSB of each event is the event type.

    > But how exactly do SDL manage to store two types at the same time in a union without corrupting either
    The 'type' is never written to (or shouldn't be).
    It's a cheap-shot way of avoiding having to do some bit-masking work to get the event type, when all you're interested in is the event type.

    > and doing so in a portable manner as well?
    I not sure that it is portable, at least not across machines with different endian.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Mar 2009
    Posts
    399
    Quote Originally Posted by Salem View Post
    > and doing so in a portable manner as well?
    I not sure that it is portable, at least not across machines with different endian.
    I don't see how there's going to be any endian issues (they are using an unsigned char for the type). The actual events that are stored in the union are structs, so I guess it all comes down to how they are aligned. I'm guessing that the struct members are stored in order in memory, with the initial alignment at the address of the union. If so, putting the type first in the struct would do the trick. I'm not sure what the C standard says about this though.

  5. #5
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> Uint8 type;

    Somebody's going to regret that someday...
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  6. #6
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Quote Originally Posted by Sebastiani View Post
    >> Uint8 type;

    Somebody's going to regret that someday...
    Why is that?

    I always thought Uint8 was a typedefed unsigned char.

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > I don't see how there's going to be any endian issues
    Yeah you're right - it seems they're all small structs beginning with a uint8 type member.

    So yes, they'll always be aligned with one another on the first member.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #8
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Memloop View Post
    SDL's implementation of this union allows you to always access the type member to see what type of event is stored.
    This involves an OR'd flag, as Salem says, the first byte of each of those structs is a member "type", whose value is always the same for a specific struct and unique to it, that's what you are accessing. Xlib uses this technique for events, etc, too. So you can have a SDL_Event* which points to a SDL_KeyboardEvent struct, determinable by checking the type.

    Works kind of like a void pointer or C++ templating for function prototypes:
    Code:
    void event_handler(SDL_Event *e);
    "e" could effectively be any one of those types, except (unlike C++ templates), you have to handle the difference internally yourself. Also unlike a template (and normative void pointer usage), you can determine the type.

    Quote Originally Posted by Subsonics View Post
    Why is that?

    I always thought Uint8 was a typedefed unsigned char.
    Maybe because you are now restricted to a mere 256 possible types.
    Last edited by MK27; 04-13-2010 at 11:30 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  9. #9
    Registered User
    Join Date
    Mar 2009
    Posts
    399
    Quote Originally Posted by Salem View Post
    > I don't see how there's going to be any endian issues
    Yeah you're right - it seems they're all small structs beginning with a uint8 type member.

    So yes, they'll always be aligned with one another on the first member.
    Wouldn't that also be true even if type is an int?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. strcmp returning 1...
    By Axel in forum C Programming
    Replies: 12
    Last Post: 09-08-2006, 07:48 PM
  2. getline() don't want to work anymore...
    By mikahell in forum C++ Programming
    Replies: 7
    Last Post: 07-31-2006, 10:50 AM
  3. Why don't the tutorials on this site work on my computer?
    By jsrig88 in forum C++ Programming
    Replies: 3
    Last Post: 05-15-2006, 10:39 PM
  4. fopen();
    By GanglyLamb in forum C Programming
    Replies: 8
    Last Post: 11-03-2002, 12:39 PM
  5. DLL __cdecl doesnt seem to work?
    By Xei in forum C++ Programming
    Replies: 6
    Last Post: 08-21-2002, 04:36 PM