weird #define statement

Discussion in 'C++' started by NKOBAYE027, Mar 2, 2004.

  1. NKOBAYE027

    NKOBAYE027 Guest

    can anyone tell me what this thing is supposed to do?

    its from the stddef.h file for MSVC 6.0

    #define offsetof(s,m) (size_t)&(((s *)0)->m)



    I understand it up to the & after that I have *no* idea what is going
    on...is s a variable or a type? what does the cast (s *) mean? is it a cast?
    and what about this 0 thing? how do we know it has an m to point at? (Oo)

    i'm clearly confused...

    any clarifications would be welcome

    regards,

    L.
    NKOBAYE027, Mar 2, 2004
    #1
    1. Advertising

  2. NKOBAYE027

    Jack Klein Guest

    On Tue, 02 Mar 2004 04:37:43 GMT, "NKOBAYE027" <>
    wrote in comp.lang.c++:

    > can anyone tell me what this thing is supposed to do?
    >
    > its from the stddef.h file for MSVC 6.0
    >
    > #define offsetof(s,m) (size_t)&(((s *)0)->m)
    >
    >
    >
    > I understand it up to the & after that I have *no* idea what is going
    > on...is s a variable or a type? what does the cast (s *) mean? is it a cast?
    > and what about this 0 thing? how do we know it has an m to point at? (Oo)
    >
    > i'm clearly confused...
    >
    > any clarifications would be welcome
    >
    > regards,
    >
    > L.


    It is the ANSI/ISO standard macro offsetof() macro that has been part
    of both the C and C++ language standards since the first 1989 ANSI C
    standard.

    It's purpose is to return a size_t value representing the offset, in
    bytes, of a structure or union member from the beginning of the
    enclosing type.

    It is up to the compiler vendor to provide an implementation that
    works with their compiler in <stdlib.h> or <cstdlib>, even though the
    macro as written might technically have undefined behavior, which this
    one does as it dereferences a null pointer. Note that an
    implementation is allowed to do things that are not technically legal
    in conforming user code.

    Finally, the offsetof() macro has very severe limitations in C++. It
    is basically valid only for POD type (pretty much C compatible)
    structs, classes, and unions.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    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, Mar 2, 2004
    #2
    1. Advertising

  3. * "NKOBAYE027" <> schriebt:
    > can anyone tell me what this thing [offsetof macro] is supposed to do?


    The offsetof macro returns the offset of member m in any struct S, like


    // Conceptual only.
    //
    // Will probably work with any C++ compiler but is formally undefined
    // due to reinterpret_cast (which would also be used by C-style cast).

    S anObject;
    char* pObject = reinterpret_cast<char*>( &anObject );
    char* pMember = reinterpret_cast<char*>( &anObject.m );

    assert( offsetof( S, m ) == pMember - pObject );


    It's a standard macro.

    But the implementation, and the assumptions built into the implementation,
    is up to the compiler vendor.



    > its from the stddef.h file for MSVC 6.0
    >
    > #define offsetof(s,m) (size_t)&(((s *)0)->m)
    >
    >
    >
    > I understand it up to the & after that I have *no* idea what is going
    > on...is s a variable or a type? what does the cast (s *) mean? is it a cast?


    Yes.


    > and what about this 0 thing? how do we know it has an m to point at? (Oo)


    It hasn't.

    If you do that yourself then you have Undefined Behavior, but the compiler
    vendor's programmers presumably knows whether it's safe with this compiler.



    > i'm clearly confused...


    Look in your documentation of 'offsetof'.

    Don't care about how it's implemented.

    But just to be complete: for this compiler it's implemented as a conversion to
    size_t of (a pointer to (member m in (a struct s located at address 0))). This
    is not guaranteed to work with other compilers. As mentioned, formally it's UB.
    Alf P. Steinbach, Mar 2, 2004
    #3
  4. NKOBAYE027

    David White Guest

    "NKOBAYE027" <> wrote in message
    news:rcU0c.62465$...
    > can anyone tell me what this thing is supposed to do?
    >
    > its from the stddef.h file for MSVC 6.0
    >
    > #define offsetof(s,m) (size_t)&(((s *)0)->m)
    >
    >
    >
    > I understand it up to the & after that I have *no* idea what is going
    > on...is s a variable or a type?


    's' is a struct or class type.

    > what does the cast (s *) mean? is it a cast?


    Yes.

    > and what about this 0 thing? how do we know it has an m to point at? (Oo)


    Because 'm' is one of the macro's parameters. The caller has to ensure that
    this parameter is a member of 's'.

    >
    > i'm clearly confused...
    >
    > any clarifications would be welcome


    (s *)0
    This converts address zero into a pointer to type 's'.

    ((s *)0)->m
    This selects member 'm' of an 's' that is at adress zero.

    &(((s *)0)->m)
    This takes the address of that member. Since the 's' begins at zero, this
    resolves to the numberof bytes the member 'm' is from the beginning of 's'.
    In other words, it is the offset of member 'm' within 's'.

    (size_t)&(((s *)0)->m)
    This converts the offset in address form into the standard integral size
    type, which you would want an offset to be.

    It would take me too long to find out how many language rules this construct
    would break if you wrote it yourself - a number of them I suspect. But it's
    their own compiler, so they know how a given non-standard construct will
    work.

    DW
    David White, Mar 2, 2004
    #4
  5. >
    > It would take me too long to find out how many language rules this

    construct
    > would break if you wrote it yourself - a number of them I suspect. But

    it's
    > their own compiler, so they know how a given non-standard construct will
    > work.


    Incidentally, has anyone seen the offsetof macro defined in any other way?
    It's hard to imagine any other technique that would work.

    john
    John Harrison, Mar 2, 2004
    #5
  6. * "John Harrison" <> schriebt:
    > >
    > > It would take me too long to find out how many language rules this

    > construct
    > > would break if you wrote it yourself - a number of them I suspect. But

    > it's
    > > their own compiler, so they know how a given non-standard construct will
    > > work.

    >
    > Incidentally, has anyone seen the offsetof macro defined in any other way?


    Don't know.


    > It's hard to imagine any other technique that would work.


    It's extremely easy to imagine other techniques, e.g.


    #define offsetof( s, m ) __offsetof( s, m )


    where __offsetof( s, m ) is a compiler intrinsic.
    Alf P. Steinbach, Mar 2, 2004
    #6
  7. >
    >
    > > It's hard to imagine any other technique that would work.

    >
    > It's extremely easy to imagine other techniques, e.g.
    >
    >
    > #define offsetof( s, m ) __offsetof( s, m )
    >
    >
    > where __offsetof( s, m ) is a compiler intrinsic.
    >


    Well, that isn't exactly what I meant.

    john
    John Harrison, Mar 2, 2004
    #7
  8. NKOBAYE027

    NKOBAYE027 Guest

    Thanks for all the great help and my apologies for the cross-post with
    comp.programming - was a snafu on my part.

    regards,
    L.

    "NKOBAYE027" <> wrote in message
    news:rcU0c.62465$...
    > can anyone tell me what this thing is supposed to do?
    >
    > its from the stddef.h file for MSVC 6.0
    >
    > #define offsetof(s,m) (size_t)&(((s *)0)->m)
    >
    >
    >
    > I understand it up to the & after that I have *no* idea what is going
    > on...is s a variable or a type? what does the cast (s *) mean? is it a

    cast?
    > and what about this 0 thing? how do we know it has an m to point at? (Oo)
    >
    > i'm clearly confused...
    >
    > any clarifications would be welcome
    >
    > regards,
    >
    > L.
    >
    >
    NKOBAYE027, Mar 2, 2004
    #8
  9. NKOBAYE027

    David White Guest

    "John Harrison" <> wrote in message
    news:c219jp$1mcu2u$-berlin.de...
    > >
    > > It would take me too long to find out how many language rules this

    > construct
    > > would break if you wrote it yourself - a number of them I suspect. But

    > it's
    > > their own compiler, so they know how a given non-standard construct will
    > > work.

    >
    > Incidentally, has anyone seen the offsetof macro defined in any other way?
    > It's hard to imagine any other technique that would work.


    I think it's a bit nasty that it turns an address directly into an integral
    type. The difference between two addresses would be more appealing, though
    more verbose.

    DW
    David White, Mar 2, 2004
    #9
    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. Paul  Erion

    converting weird #define to const

    Paul Erion, Feb 8, 2005, in forum: C++
    Replies:
    4
    Views:
    373
    Mike Wahler
    Feb 9, 2005
  2. theotyflos
    Replies:
    3
    Views:
    463
    Thomas Matthews
    Feb 19, 2004
  3. robin liu
    Replies:
    3
    Views:
    821
    Robin Liu
    Apr 21, 2006
  4. dorayme
    Replies:
    1
    Views:
    610
    richard
    Jan 21, 2011
  5. Brian Takita

    #define _ and #define __

    Brian Takita, Jan 23, 2006, in forum: Ruby
    Replies:
    0
    Views:
    457
    Brian Takita
    Jan 23, 2006
Loading...

Share This Page