memory offset of member variable within class

Discussion in 'C++' started by John Goche, Nov 6, 2006.

  1. John Goche

    John Goche Guest

    Hello,

    Consider the following macro to get the
    memory offset of a class data member:

    #define OFFSET(CLASSNAME, MEMBER) ((int) (&((CLASSNAME *) 0)->MEMBER))

    Given that 0 may not be the address of
    an instance of CLASSNAME, will this
    code be legal in standard C++?

    Thanks,

    JG
     
    John Goche, Nov 6, 2006
    #1
    1. Advertising

  2. John Goche wrote:
    > Consider the following macro to get the
    > memory offset of a class data member:
    >
    > #define OFFSET(CLASSNAME, MEMBER) ((int) (&((CLASSNAME *) 0)->MEMBER))
    >
    > Given that 0 may not be the address of
    > an instance of CLASSNAME, will this
    > code be legal in standard C++?


    Nit: the code is just a definition. It's ignored unless you actually
    use the macro. You didn't use the macro.

    Now, if the macro is used, then yes, but only if a POD struct is the
    first argument.

    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, Nov 6, 2006
    #2
    1. Advertising

  3. John Goche:

    > Consider the following macro to get the
    > memory offset of a class data member:
    >
    > #define OFFSET(CLASSNAME, MEMBER) ((int) (&((CLASSNAME *) 0)->MEMBER))
    >
    > Given that 0 may not be the address of
    > an instance of CLASSNAME, will this
    > code be legal in standard C++?



    The C++ Standard does not define the behaviour of the deferencing of a null
    pointer.

    In your example:

    ((T*)0)->field

    is equal to:

    (*(T*)0).field

    As you can see, a null pointer is dereferenced.

    --

    Frederick Gotham
     
    Frederick Gotham, Nov 6, 2006
    #3
  4. John Goche wrote:
    > Hello,
    >
    > Consider the following macro to get the
    > memory offset of a class data member:
    >
    > #define OFFSET(CLASSNAME, MEMBER) ((int) (&((CLASSNAME *) 0)->MEMBER))
    >
    > Given that 0 may not be the address of
    > an instance of CLASSNAME, will this
    > code be legal in standard C++?



    This kind of "address of" operator is replaced with "address of member".
    i.e.

    struct A { int b; int c; };

    int A::* x = & A::b;

    x = & A::c;

    See if your code can be changed to use this C++ construct.
     
    Gianni Mariani, Nov 6, 2006
    #4
  5. John Goche

    Kavya Guest

    Frederick Gotham wrote:
    >
    > The C++ Standard does not define the behaviour of the deferencing of a null
    > pointer.
    >
    > In your example:
    >
    > ((T*)0)->field
    >
    > is equal to:
    >
    > (*(T*)0).field
    >
    > As you can see, a null pointer is dereferenced.
    >


    Derefrencing a null pointer in not undefined behavior. Using the
    resulting value is undefined behavior.
     
    Kavya, Nov 6, 2006
    #5
  6. Kavya wrote:
    > Frederick Gotham wrote:
    >> The C++ Standard does not define the behaviour of the deferencing of a null
    >> pointer.
    >>
    >> In your example:
    >>
    >> ((T*)0)->field
    >>
    >> is equal to:
    >>
    >> (*(T*)0).field
    >>
    >> As you can see, a null pointer is dereferenced.
    >>

    >
    > Derefrencing a null pointer in not undefined behavior. Using the
    > resulting value is undefined behavior.
    >


    Actually, it is undefined. Practically every compiler I know does not
    do anything "unexpected", that's a different story. I do think that the
    standard should allow it though. Member addresses (T S::*) IMHO is a
    much better alternative.
     
    Gianni Mariani, Nov 6, 2006
    #6
  7. Just to clarify the misinformation posted in this thread.

    (1) The behaviour produced as a result of dereferencing a null pointer is
    not defined by the C++ Standard.
    (2) The behaviour of pointer arithmetic upon a null pointer is not defined
    by the C++ Standard.
    (3) The nature of pointer arithmetic is entirely up to the implementor, and
    the C++ Standard does not necessitate that it operate in the same fashion
    as integer arithmetic.

    Therefore, the behaviour of the following expression upon its evaluation is
    undefined:

    *(T*)0

    Furthermore, the behaviour of the following expression upon its evaluation
    is undefined:

    (*(T*)0).field

    As is:

    ((T*)0)->field

    As is:

    &((T*)0)->field

    Even it the dereferencing of a null pointer did not invoke undefined
    behaviour, the evaluation to false of the following expression would still
    not be guaranteed.

    (T*)0 + 1 - 1

    --

    Frederick Gotham
     
    Frederick Gotham, Nov 6, 2006
    #7
  8. John Goche

    Jack Klein Guest

    On 6 Nov 2006 13:55:31 -0800, "Kavya" <> wrote in
    comp.lang.c++:

    >
    > Frederick Gotham wrote:
    > >
    > > The C++ Standard does not define the behaviour of the deferencing of a null
    > > pointer.
    > >
    > > In your example:
    > >
    > > ((T*)0)->field
    > >
    > > is equal to:
    > >
    > > (*(T*)0).field
    > >
    > > As you can see, a null pointer is dereferenced.
    > >

    >
    > Derefrencing a null pointer in not undefined behavior. Using the
    > resulting value is undefined behavior.


    Just plain old flat out wrong. Literally contradicted in so many
    words by the C++ standard, no subtle interpretations needed.

    Paragraph 4 of 1.9:

    "Certain other operations are described in this International Standard
    as undefined (for example, the effect of dereferencing the null
    pointer). [Note: this International Standard imposes no requirements
    on the behavior of programs that contain undefined behavior.]"

    Has nothing at all to do with what you do or do not try to do with the
    resulting value. In fact, there is no "resulting value". Since the
    C++ standard also states (paragraph 1 of 4.10:

    "A null pointer constant is an integral constant expression (5.19)
    rvalue of integer type that evaluates to zero. A null pointer constant
    can be converted to a pointer type; the result is the null pointer
    value of that type and is distinguishable from every other value of
    pointer to object or pointer to function type."

    ....a null pointer does not point to any object or function, there
    since it points to nothing there is no value to be had.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://c-faq.com/
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, Nov 7, 2006
    #8
  9. John Goche

    Kavya Guest

    Jack Klein wrote:
    > On 6 Nov 2006 13:55:31 -0800, "Kavya" <> wrote in
    > comp.lang.c++:
    >
    > >
    > > Frederick Gotham wrote:
    > > >
    > > > The C++ Standard does not define the behaviour of the deferencing of a null
    > > > pointer.
    > > >
    > > > In your example:
    > > >
    > > > ((T*)0)->field
    > > >
    > > > is equal to:
    > > >
    > > > (*(T*)0).field
    > > >
    > > > As you can see, a null pointer is dereferenced.
    > > >

    > >
    > > Derefrencing a null pointer in not undefined behavior. Using the
    > > resulting value is undefined behavior.

    >
    > Just plain old flat out wrong. Literally contradicted in so many
    > words by the C++ standard, no subtle interpretations needed.
    >
    > Paragraph 4 of 1.9:
    >
    > "Certain other operations are described in this International Standard
    > as undefined (for example, the effect of dereferencing the null
    > pointer). [Note: this International Standard imposes no requirements
    > on the behavior of programs that contain undefined behavior.]"
    >
    > Has nothing at all to do with what you do or do not try to do with the
    > resulting value. In fact, there is no "resulting value". Since the
    > C++ standard also states (paragraph 1 of 4.10:
    >
    > "A null pointer constant is an integral constant expression (5.19)
    > rvalue of integer type that evaluates to zero. A null pointer constant
    > can be converted to a pointer type; the result is the null pointer
    > value of that type and is distinguishable from every other value of
    > pointer to object or pointer to function type."
    >
    > ...a null pointer does not point to any object or function, there
    > since it points to nothing there is no value to be had.
    >


    Sir, can you please look at this
    http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#232
     
    Kavya, Nov 7, 2006
    #9
  10. John Goche

    Steve Pope Guest

    If I were an implementer, I would want my implementation to
    be free to possibly seg-fault if address zero, or an address one past
    and array, were dereferenced.

    Unless you'all are using a different definition of "dereference"
    than I am...

    S.
     
    Steve Pope, Nov 7, 2006
    #10
    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. DJ Dev
    Replies:
    3
    Views:
    16,138
    Gandalf
    Feb 8, 2004
  2. E11
    Replies:
    1
    Views:
    4,792
    Thomas Weidenfeller
    Oct 12, 2005
  3. Lance Riedel

    Translated Offset to Source Offset

    Lance Riedel, Oct 14, 2003, in forum: XML
    Replies:
    2
    Views:
    504
    Patrick TJ McPhee
    Oct 15, 2003
  4. Rahul
    Replies:
    19
    Views:
    637
    Serge Paccalin
    Nov 15, 2006
  5. Roy Smith
    Replies:
    4
    Views:
    278
    Roy Smith
    Jan 27, 2013
Loading...

Share This Page