a C++ question about union

Discussion in 'C++' started by JDT, Apr 23, 2007.

  1. JDT

    JDT Guest

    NM_UPDOWN

    With UDN_DELTAPOS notification handler, MS passes a pointer to NMHDR
    which yo can cast to NM_UPDOWN*. With NMHDR (shown below) , you can use
    "iDelta" to know the amount it spins while with NMHDR you can use "code"
    to know the event type. What I don't understand is why the same storage
    (the overlap of the last int and unsigned int) can provide two different
    values by casting. Is it not union, is it? This is a C++ (or even a C)
    question. If I underhand it, I may exploit the same tech for my own.
    Your advise is appreciated. JD

    typedef struct _NM_UPDOWN
    {
    NMHDR hdr;
    int iPos;
    int iDelta;
    } NMUPDOWN, *LPNMUPDOWN;

    typedef struct tagNMHDR
    {
    HWND hwndFrom;
    UINT_PTR idFrom;
    UINT code; // NM_ code
    } NMHDR;
     
    JDT, Apr 23, 2007
    #1
    1. Advertising

  2. JDT wrote:
    > NM_UPDOWN
    >
    > With UDN_DELTAPOS notification handler, MS passes a pointer to NMHDR
    > which yo can cast to NM_UPDOWN*. With NMHDR (shown below) , you can
    > use "iDelta" to know the amount it spins while with NMHDR you can use
    > "code" to know the event type. What I don't understand is why the
    > same storage (the overlap of the last int and unsigned int) can
    > provide two different values by casting. Is it not union, is it? This is
    > a C++ (or even a C) question. If I underhand it, I may
    > exploit the same tech for my own. Your advise is appreciated. JD
    >
    > typedef struct _NM_UPDOWN
    > {
    > NMHDR hdr;
    > int iPos;
    > int iDelta;
    > } NMUPDOWN, *LPNMUPDOWN;
    >
    > typedef struct tagNMHDR
    > {
    > HWND hwndFrom;
    > UINT_PTR idFrom;
    > UINT code; // NM_ code
    > } NMHDR;


    So much MS stuff here, my head hurts... Perhaps next time you will
    rephrase to avoid using their abbreivations and all-capital-letters
    names... It would be so nice...

    Anyway, what you're asking about is akin to the fact that if I have
    a "hierarchy" like this

    struct A {
    int a;
    };

    struct B {
    A a;
    double d;
    };

    , I could do the following:

    #include <iostream>
    void foo(A* pa) {
    B* pb = (B*) pa;
    std::cout << "The 'd' is " << pb->d << std::endl;
    }

    int main() {
    B b = { { 42 }, 3.14159 };
    foo(& b.a);
    }

    Well, yes, that's "allowed". The layout of any POD object is pretty
    much preset, in the sense that 'd' follows 'a' in a 'B' and that the
    address of 'a' in a 'B' is the same as the address of the 'B' itself.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Apr 23, 2007
    #2
    1. Advertising

  3. JDT

    Ian Collins Guest

    JDT wrote:
    > NM_UPDOWN
    >
    > With UDN_DELTAPOS notification handler, MS passes a pointer to NMHDR
    > which yo can cast to NM_UPDOWN*. With NMHDR (shown below) , you can use
    > "iDelta" to know the amount it spins while with NMHDR you can use "code"
    > to know the event type. What I don't understand is why the same storage
    > (the overlap of the last int and unsigned int) can provide two different
    > values by casting. Is it not union, is it? This is a C++ (or even a C)
    > question. If I underhand it, I may exploit the same tech for my own.
    > Your advise is appreciated. JD
    >

    It's not a technique, it's a horrible kludge.

    --
    Ian Collins.
     
    Ian Collins, Apr 23, 2007
    #3
  4. JDT

    Andre Kostur Guest

    JDT <> wrote in news:_x7Xh.7473$H_5.4975
    @newssvr23.news.prodigy.net:

    > NM_UPDOWN
    >
    > With UDN_DELTAPOS notification handler, MS passes a pointer to NMHDR
    > which yo can cast to NM_UPDOWN*. With NMHDR (shown below) , you can

    use
    > "iDelta" to know the amount it spins while with NMHDR you can use

    "code"
    > to know the event type. What I don't understand is why the same

    storage
    > (the overlap of the last int and unsigned int) can provide two

    different
    > values by casting. Is it not union, is it? This is a C++ (or even a

    C)
    > question. If I underhand it, I may exploit the same tech for my own.
    > Your advise is appreciated. JD
    >
    > typedef struct _NM_UPDOWN
    > {
    > NMHDR hdr;
    > int iPos;
    > int iDelta;
    > } NMUPDOWN, *LPNMUPDOWN;
    >
    > typedef struct tagNMHDR
    > {
    > HWND hwndFrom;
    > UINT_PTR idFrom;
    > UINT code; // NM_ code
    > } NMHDR;
    >


    This is more of a C question than C++, but here goes:


    Note that the first member of _NM_UPDOWN is an NMHDR.

    So what MS is doing behind the scenes is something like:


    {
    _NM_UPDOWN notification;

    notification.hdr.code = NM_WhateverCode;

    CallNotificationFunction(reinterpret_cast<NMHDR *>(&notification);
    }


    Basically it's relying on the fact that the first part of the NM_UPDOWN
    struct actually is a NMHDR object. It's kinda trying to implement
    inheritance in the C world.

    So when MS is passing you a pointer to NMHDR, it's really passing you a
    pointer to the hdr member of an NM_UPDOWN struct. Keep in mind that the
    pointer to the first member of a struct is the same as a pointer to the
    struct itself.
     
    Andre Kostur, Apr 23, 2007
    #4
  5. Ian Collins wrote:
    > JDT wrote:
    >> NM_UPDOWN
    >>
    >> With UDN_DELTAPOS notification handler, MS passes a pointer to NMHDR
    >> which yo can cast to NM_UPDOWN*. With NMHDR (shown below) , you can
    >> use "iDelta" to know the amount it spins while with NMHDR you can
    >> use "code" to know the event type. What I don't understand is why
    >> the same storage (the overlap of the last int and unsigned int) can
    >> provide two different values by casting. Is it not union, is it?
    >> This is a C++ (or even a C) question. If I underhand it, I may
    >> exploit the same tech for my own. Your advise is appreciated. JD
    >>

    > It's not a technique, it's a horrible kludge.


    [Mostly directed at the OP]

    IOW, there are more reliable ways to do that in C++. However, in C,
    since there is no inheritance, relying on certain relationship
    between a pointer to a struct member and and the struct object itself
    is not completely unheard of. Think "offsetof" macro.

    And since we are in a C++ newsgroup, there is probably more merit in
    stating what problem you're trying to solve, so that a solution or
    two (or three) can be proposed, instead of showing some other solution
    to some other problem in an attempt to see if it solves something else
    you have not encountered yet...

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Apr 23, 2007
    #5
  6. JDT

    Ian Collins Guest

    Victor Bazarov wrote:
    > Ian Collins wrote:
    >
    >>JDT wrote:
    >>
    >>>NM_UPDOWN
    >>>
    >>>With UDN_DELTAPOS notification handler, MS passes a pointer to NMHDR
    >>>which yo can cast to NM_UPDOWN*. With NMHDR (shown below) , you can
    >>>use "iDelta" to know the amount it spins while with NMHDR you can
    >>>use "code" to know the event type. What I don't understand is why
    >>>the same storage (the overlap of the last int and unsigned int) can
    >>>provide two different values by casting. Is it not union, is it?
    >>>This is a C++ (or even a C) question. If I underhand it, I may
    >>>exploit the same tech for my own. Your advise is appreciated. JD
    >>>

    >>
    >>It's not a technique, it's a horrible kludge.

    >
    >
    > [Mostly directed at the OP]
    >
    > IOW, there are more reliable ways to do that in C++. However, in C,
    > since there is no inheritance, relying on certain relationship
    > between a pointer to a struct member and and the struct object itself
    > is not completely unheard of. Think "offsetof" macro.
    >

    It's still a horrible kludge. If you want to do such things in C, use a
    union of structures with the first member of each struct being the type
    identifier.

    --
    Ian Collins.
     
    Ian Collins, Apr 23, 2007
    #6
  7. Ian Collins wrote:
    > Victor Bazarov wrote:
    >> Ian Collins wrote:
    >>
    >>> JDT wrote:
    >>>
    >>>> NM_UPDOWN
    >>>>
    >>>> With UDN_DELTAPOS notification handler, MS passes a pointer to
    >>>> NMHDR which yo can cast to NM_UPDOWN*. With NMHDR (shown below) ,
    >>>> you can use "iDelta" to know the amount it spins while with NMHDR
    >>>> you can use "code" to know the event type. What I don't
    >>>> understand is why the same storage (the overlap of the last int
    >>>> and unsigned int) can provide two different values by casting. Is
    >>>> it not union, is it? This is a C++ (or even a C) question. If I
    >>>> underhand it, I may exploit the same tech for my own. Your advise
    >>>> is appreciated. JD
    >>>>
    >>>
    >>> It's not a technique, it's a horrible kludge.

    >>
    >>
    >> [Mostly directed at the OP]
    >>
    >> IOW, there are more reliable ways to do that in C++. However, in C,
    >> since there is no inheritance, relying on certain relationship
    >> between a pointer to a struct member and and the struct object itself
    >> is not completely unheard of. Think "offsetof" macro.
    >>

    > It's still a horrible kludge. If you want to do such things in C,
    > use a union of structures with the first member of each struct being
    > the type identifier.


    I don't see how it's better, and that's probably why I don't understand
    the "horrible" attribute you used in your charcterisation.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Apr 23, 2007
    #7
  8. JDT

    Ian Collins Guest

    Victor Bazarov wrote:
    > Ian Collins wrote:
    >
    >>Victor Bazarov wrote:
    >>
    >>>Ian Collins wrote:
    >>>
    >>>>JDT wrote:
    >>>>
    >>>>>NM_UPDOWN
    >>>>>
    >>>>>With UDN_DELTAPOS notification handler, MS passes a pointer to
    >>>>>NMHDR which yo can cast to NM_UPDOWN*. With NMHDR (shown below) ,
    >>>>>you can use "iDelta" to know the amount it spins while with NMHDR
    >>>>>you can use "code" to know the event type. What I don't
    >>>>>understand is why the same storage (the overlap of the last int
    >>>>>and unsigned int) can provide two different values by casting. Is
    >>>>>it not union, is it? This is a C++ (or even a C) question. If I
    >>>>>underhand it, I may exploit the same tech for my own. Your advise
    >>>>>is appreciated. JD
    >>>>
    >>>>It's not a technique, it's a horrible kludge.
    >>>
    >>>[Mostly directed at the OP]
    >>>
    >>>IOW, there are more reliable ways to do that in C++. However, in C,
    >>>since there is no inheritance, relying on certain relationship
    >>>between a pointer to a struct member and and the struct object itself
    >>>is not completely unheard of. Think "offsetof" macro.

    >>
    >>It's still a horrible kludge. If you want to do such things in C,
    >>use a union of structures with the first member of each struct being
    >>the type identifier.

    >
    > I don't see how it's better, and that's probably why I don't understand
    > the "horrible" attribute you used in your charcterisation.
    >

    Posting pre-coffee....

    I should have written If you want to do such things in C, use a union of
    structures with the first member of each struct and the union being the
    type identifier, thus:

    struct A {
    int type;
    /* Other members */
    };

    struct B {
    int type;
    /* Other members */
    };

    typedef union {
    int type;
    struct A a;
    struct B b;
    } Event;

    It is then clear to the reader what an Event is and which types of event
    are supported.

    --
    Ian Collins.
     
    Ian Collins, Apr 23, 2007
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Matt Garman
    Replies:
    1
    Views:
    691
    Matt Garman
    Apr 25, 2004
  2. Luca

    union question

    Luca, Aug 27, 2003, in forum: C++
    Replies:
    3
    Views:
    332
    Ron Natalie
    Sep 2, 2003
  3. Peter Dunker

    union in struct without union name

    Peter Dunker, Apr 26, 2004, in forum: C Programming
    Replies:
    2
    Views:
    924
    Chris Torek
    Apr 26, 2004
  4. =?gb2312?B?zfWzrLey?=

    About Union's question

    =?gb2312?B?zfWzrLey?=, Mar 30, 2007, in forum: C Programming
    Replies:
    32
    Views:
    976
    CBFalconer
    Apr 2, 2007
  5. Art Spasky

    Question about union operator (|)

    Art Spasky, Aug 30, 2007, in forum: XML
    Replies:
    18
    Views:
    1,439
    Richard Tobin
    Sep 3, 2007
Loading...

Share This Page