offset of a member inside a structure

Discussion in 'C Programming' started by junky_fellow, Oct 14, 2004.

  1. junky_fellow

    junky_fellow Guest

    I am trying to find the offset of a member "mbr" inside a structure
    "str" as follows:

    offset = &(struct str *)0->mbr;

    But, on compilation I get the following error:
    cc: Error: m1.c, line 55: In this statement, "0" has a signed int
    type, but occurs in a context that requires a pointer. (needpointer)

    Can anybody point out where the problem is ?

    Thanx for any help in advance....
    junky_fellow, Oct 14, 2004
    #1
    1. Advertising

  2. junky_fellow

    Chris Dollin Guest

    junky_fellow wrote:

    > I am trying to find the offset of a member "mbr" inside a structure
    > "str" as follows:
    >
    > offset = &(struct str *)0->mbr;
    >
    > But, on compilation I get the following error:
    > cc: Error: m1.c, line 55: In this statement, "0" has a signed int
    > type, but occurs in a context that requires a pointer. (needpointer)
    >
    > Can anybody point out where the problem is ?


    Yes. You're not using the offsetof macro from <stddef.h>.

    [The expression `(type) foo->bar` parses as `(type) (foo->bar)`. You
    needed `&((struct str *)0)->mbr` for what you were trying to do.
    However, what you're trying to do (a) has undefined behaviour and
    (b) doesn't return what I (at least) think of as the "offset" of
    a member, in plausible implementations. What, exactly, *are* you
    trying to do?]


    --
    Chris "electric hedgehog" Dollin
    Chris Dollin, Oct 14, 2004
    #2
    1. Advertising

  3. junky_fellow wrote:
    >
    > I am trying to find the offset of a member "mbr" inside a structure
    > "str" as follows:
    >
    > offset = &(struct str *)0->mbr;
    >
    > But, on compilation I get the following error:
    > cc: Error: m1.c, line 55: In this statement, "0" has a signed int
    > type, but occurs in a context that requires a pointer. (needpointer)
    >
    > Can anybody point out where the problem is ?


    I believe that "->" has higher precedence than the cast. (Though if
    I'm wrong, someone will be along shortly to correct that.)

    Try:

    offset = &(((struct str *)0)->mbr);

    My C compiler has:

    #define offsetof(__typ,__id) ((size_t)&(((__typ*)0)->__id))

    --
    +-------------------------+--------------------+-----------------------------+
    | Kenneth J. Brody | www.hvcomputer.com | |
    | kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
    +-------------------------+--------------------+-----------------------------+
    Kenneth Brody, Oct 14, 2004
    #3
  4. junky_fellow

    Michael Mair Guest

    Hi Chris,


    Chris Dollin wrote:
    > junky_fellow wrote:
    >
    >
    >>I am trying to find the offset of a member "mbr" inside a structure
    >>"str" as follows:
    >>
    >>offset = &(struct str *)0->mbr;
    >>
    >>But, on compilation I get the following error:
    >>cc: Error: m1.c, line 55: In this statement, "0" has a signed int
    >>type, but occurs in a context that requires a pointer. (needpointer)
    >>
    >>Can anybody point out where the problem is ?

    >
    >
    > Yes. You're not using the offsetof macro from <stddef.h>.
    >
    > [The expression `(type) foo->bar` parses as `(type) (foo->bar)`. You
    > needed `&((struct str *)0)->mbr` for what you were trying to do.
    > However, what you're trying to do (a) has undefined behaviour and
    > (b) doesn't return what I (at least) think of as the "offset" of
    > a member, in plausible implementations. What, exactly, *are* you
    > trying to do?]


    Well, apart from the fact that the standard headers can of course
    do what they want in an implementation defined way as long as they
    provide what the standard demands in the way the standard demands:
    In most implementations I know you find offsetof to be defined along
    the lines of
    #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
    with differences mainly in the size_t typecast.

    So, maybe the OP has seen this somewhere and wanted to reproduce it.

    BTW: Does this really invoke UB?


    Cheers
    Michael
    Michael Mair, Oct 14, 2004
    #4
  5. junky_fellow

    Chris Dollin Guest

    Michael Mair wrote:

    > Hi Chris,
    > Chris Dollin wrote:
    >> junky_fellow wrote:
    >>
    >>
    >>>I am trying to find the offset of a member "mbr" inside a structure
    >>>"str" as follows:
    >>>
    >>>offset = &(struct str *)0->mbr;
    >>>
    >>>But, on compilation I get the following error:
    >>>cc: Error: m1.c, line 55: In this statement, "0" has a signed int
    >>>type, but occurs in a context that requires a pointer. (needpointer)
    >>>
    >>>Can anybody point out where the problem is ?

    >>
    >>
    >> Yes. You're not using the offsetof macro from <stddef.h>.
    >>
    >> [The expression `(type) foo->bar` parses as `(type) (foo->bar)`. You
    >> needed `&((struct str *)0)->mbr` for what you were trying to do.
    >> However, what you're trying to do (a) has undefined behaviour and
    >> (b) doesn't return what I (at least) think of as the "offset" of
    >> a member, in plausible implementations. What, exactly, *are* you
    >> trying to do?]

    >
    > Well, apart from the fact that the standard headers can of course
    > do what they want in an implementation defined way as long as they
    > provide what the standard demands in the way the standard demands:


    More importantly, an implementation's standard headers can assume
    properties of that implementation ...

    > In most implementations I know you find offsetof to be defined along
    > the lines of
    > #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
    > with differences mainly in the size_t typecast.
    >
    > So, maybe the OP has seen this somewhere and wanted to reproduce it.
    >
    > BTW: Does this really invoke UB?


    I believe so, but the last time I remember going round the discussion,
    it depended on exactly how much wiggle-room one thought there was in
    the Standard, and whether the expression

    &pointer->member

    had to be viewed as dereferencing `pointer`.

    My view is: I would not do that, unless I had to; if I had to, I would
    document that I did it and put tests in the test-suite to guard it; I
    would expect it to work on most any platform I actually used, whether or
    not I used it.

    And for getting offsets, I would use offsetof. Why make trouble for
    oneself, when there's already enough to hand?

    --
    Chris "electric hedgehog" Dollin
    Chris Dollin, Oct 14, 2004
    #5
  6. junky_fellow wrote:
    >
    > I am trying to find the offset of a member "mbr" inside a structure
    > "str" as follows:
    >
    > offset = &(struct str *)0->mbr;
    >
    > But, on compilation I get the following error:
    > cc: Error: m1.c, line 55: In this statement, "0" has a signed int
    > type, but occurs in a context that requires a pointer. (needpointer)
    >
    > Can anybody point out where the problem is ?
    >
    > Thanx for any help in advance....


    As the error message states, 0 is an int, not a pointer. Use NULL.

    --
    Fred L. Kleinschmidt
    Boeing Associate Technical Fellow
    Technical Architect, Common User Interface Services
    M/S 2R-94 (206)544-5225
    Fred L. Kleinschmidt, Oct 14, 2004
    #6
  7. Fred L. Kleinschmidt wrote:
    >
    > As the error message states, 0 is an int, not a pointer. Use NULL.
    >


    No, use the offsetof macro. Anything else is undefined behaviour.

    --
    Thomas.
    Thomas Stegen, Oct 14, 2004
    #7
  8. Kenneth Brody wrote:
    > Try:
    >
    > offset = &(((struct str *)0)->mbr);


    Undefined behaviour.

    >
    > My C compiler has:


    And luckily, they all do :)

    >
    > #define offsetof(__typ,__id) ((size_t)&(((__typ*)0)->__id))
    >


    Use this macro instead. The headers of a specific system can do
    magic you cannot do.

    --
    Thomas.
    Thomas Stegen, Oct 14, 2004
    #8
  9. junky_fellow

    Michael Mair Guest

    Chris Dollin wrote:
    > Michael Mair wrote:
    >>Chris Dollin wrote:
    >>>junky_fellow wrote:
    >>>
    >>>>I am trying to find the offset of a member "mbr" inside a structure
    >>>>"str" as follows:
    >>>>
    >>>>offset = &(struct str *)0->mbr;
    >>>>
    >>>>But, on compilation I get the following error:
    >>>>cc: Error: m1.c, line 55: In this statement, "0" has a signed int
    >>>>type, but occurs in a context that requires a pointer. (needpointer)
    >>>>
    >>>>Can anybody point out where the problem is ?
    >>>
    >>>
    >>>Yes. You're not using the offsetof macro from <stddef.h>.
    >>>
    >>>[The expression `(type) foo->bar` parses as `(type) (foo->bar)`. You
    >>> needed `&((struct str *)0)->mbr` for what you were trying to do.
    >>> However, what you're trying to do (a) has undefined behaviour and
    >>> (b) doesn't return what I (at least) think of as the "offset" of
    >>> a member, in plausible implementations. What, exactly, *are* you
    >>> trying to do?]

    >>
    >>Well, apart from the fact that the standard headers can of course
    >>do what they want in an implementation defined way as long as they
    >>provide what the standard demands in the way the standard demands:

    >
    > More importantly, an implementation's standard headers can assume
    > properties of that implementation ...


    Should have written it that way... Thanks for putting it
    more clearly :)


    >>In most implementations I know you find offsetof to be defined along
    >>the lines of
    >> #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
    >>with differences mainly in the size_t typecast.
    >>
    >>So, maybe the OP has seen this somewhere and wanted to reproduce it.
    >>
    >>BTW: Does this really invoke UB?

    >
    >
    > I believe so, but the last time I remember going round the discussion,
    > it depended on exactly how much wiggle-room one thought there was in
    > the Standard, and whether the expression
    >
    > &pointer->member
    >
    > had to be viewed as dereferencing `pointer`.


    Okay, so it is open to some debate. I just looked at it and thought
    "With some imagination it does not even dereference anything, gives
    you ptrdiff_t or whatever you need... Could work".
    The discussions you probably referred to (I googled for offsetof in
    comp.lang.c and comp.std.c and had a look at the first ten hits)
    basically say(*) it is UB but works most of the time.


    > My view is: I would not do that, unless I had to; if I had to, I would
    > document that I did it and put tests in the test-suite to guard it; I
    > would expect it to work on most any platform I actually used, whether or
    > not I used it.
    >
    > And for getting offsets, I would use offsetof. Why make trouble for
    > oneself, when there's already enough to hand?


    Yes, of course -- I do not disagree; I was just puzzled as I could
    not derive from the standard whether it works always and everywhere.


    Cheers
    Michael

    (*) Read: The comments of the regulars I trust to know the standard
    very well and certainly better than me tend on average to say...
    Michael Mair, Oct 14, 2004
    #9
  10. In article <416E933F.8F74D153@nospam_boeing.com>,
    Fred L. Kleinschmidt <fred.l.kleinschmidt@nospam_boeing.com> wrote:

    >As the error message states, 0 is an int, not a pointer. Use NULL.


    That's not the problem. Others have correctly explained it.

    Changing the 0 to NULL does not change the error message on the system
    I use, nor on many others. Which is not surprising, since it has

    #define NULL 0

    in stdio.h.

    -- Richard
    Richard Tobin, Oct 14, 2004
    #10
  11. junky_fellow

    Dan Pop Guest

    In <416E933F.8F74D153@nospam_boeing.com> "Fred L. Kleinschmidt" <fred.l.kleinschmidt@nospam_boeing.com> writes:


    >
    >junky_fellow wrote:
    >>
    >> I am trying to find the offset of a member "mbr" inside a structure
    >> "str" as follows:
    >>
    >> offset = &(struct str *)0->mbr;
    >>
    >> But, on compilation I get the following error:
    >> cc: Error: m1.c, line 55: In this statement, "0" has a signed int
    >> type, but occurs in a context that requires a pointer. (needpointer)
    >>
    >> Can anybody point out where the problem is ?
    >>
    >> Thanx for any help in advance....

    >
    >As the error message states, 0 is an int, not a pointer. Use NULL.


    Don't be idiot! NULL may as well expand to a plain 0. The "right"
    fix is to add the badly needed parentheses. And the right fix is to use
    the offsetof macro instead. That's one wheel of the standard C library
    that is best not reinvented.

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
    Currently looking for a job in the European Union
    Dan Pop, Oct 14, 2004
    #11
  12. junky_fellow

    Flash Gordon Guest

    On Thu, 14 Oct 2004 16:24:12 +0100
    Thomas Stegen <> wrote:

    > Fred L. Kleinschmidt wrote:
    > >
    > > As the error message states, 0 is an int, not a pointer. Use NULL.
    > >

    >
    > No, use the offsetof macro. Anything else is undefined behaviour.


    In addition NULL could be defined as plain 0 so using it might not
    change anything.
    --
    Flash Gordon
    Sometimes I think shooting would be far too good for some people.
    Although my email address says spam, it is real and I read it.
    Flash Gordon, Oct 14, 2004
    #12
  13. Chris Dollin wrote:

    > Michael Mair wrote:

    <snip>
    >>
    >>BTW: Does this really invoke UB?

    >
    >
    > I believe so, but the last time I remember going round the discussion,
    > it depended on exactly how much wiggle-room one thought there was in
    > the Standard, and whether the expression
    >
    > &pointer->member
    >
    > had to be viewed as dereferencing `pointer`.

    <snip>

    Implementations are allowed to be stupid, even if the stupidity borders
    on maliciousness. If compiled and executed on the Deathstation 9000,
    for example, this statement causes nuclear war, unfortunately.

    In all seriousness, the consensus was that it invokes undefined behavior.



    Mark F. Haigh
    Mark F. Haigh, Oct 15, 2004
    #13
  14. junky_fellow

    Tim Rentsch Guest

    Chris Dollin <> writes:

    > Michael Mair wrote:
    >
    > > In most implementations I know you find offsetof to be defined along
    > > the lines of
    > > #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
    > > with differences mainly in the size_t typecast.


    My comment here is mainly about this definition. I understand
    that normally it's better to use an implementation-supplied
    'offsetof()' rather than writing one's own. However, if one
    were to want to write one, would not the definition

    #define offsetof(TYPE,MEMBER) \
    ((size_t) ( \
    (char*) &((TYPE *)0)->MEMBER - (char*) &(*(TYPE *)0) \
    ))

    be more likely to yield more-portably correct results?


    > > BTW: Does this really invoke UB?

    >
    > I believe so, but the last time I remember going round the discussion,
    > it depended on exactly how much wiggle-room one thought there was in
    > the Standard, and whether the expression
    >
    > &pointer->member
    >
    > had to be viewed as dereferencing `pointer`.


    Presumably if one definition invokes UB then the other does (and vice
    versa?). That notwithstanding, however (or alternatively, if one were
    writing 'offsetof()' as part of a C implementation), doesn't the
    subtractive definition seem a little cleaner than the earlier one?
    Tim Rentsch, Oct 21, 2004
    #14
  15. junky_fellow

    Chris Torek Guest

    In article <news:>
    Tim Rentsch <> wrote:
    >... I understand
    >that normally it's better to use an implementation-supplied
    >'offsetof()' rather than writing one's own. However, if one
    >were to want to write one, would not the definition
    >
    > #define offsetof(TYPE,MEMBER) \
    > ((size_t) ( \
    > (char*) &((TYPE *)0)->MEMBER - (char*) &(*(TYPE *)0) \
    > ))
    >
    >be more likely to yield more-portably correct results?


    Aside from the extra "&", this is the one in the comp.lang.c FAQ
    (question 2.14).

    >Presumably if one definition invokes UB then the other does (and vice
    >versa?). That notwithstanding, however (or alternatively, if one were
    >writing 'offsetof()' as part of a C implementation), doesn't the
    >subtractive definition seem a little cleaner than the earlier one?


    Implementors are, of course, allowed to be "arbitrarily dirty" since
    they (presumably) control the horizontal and the vertical. Perhaps
    offsetof() is #define'd as:

    #define offsetof(t, f) _O_O_(f, t)

    for instance. :) The subtractive version would in general remove
    any "nonzero null pointer bias" that might be left behind without
    the subtraction, but one would certainly hope that the implementor
    knows how he implemented his null pointers.
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
    Chris Torek, Oct 23, 2004
    #15
  16. junky_fellow

    Tim Rentsch Guest

    Chris Torek <> writes:

    > In article <news:>
    > Tim Rentsch <> wrote:
    > >... I understand
    > >that normally it's better to use an implementation-supplied
    > >'offsetof()' rather than writing one's own. However, if one
    > >were to want to write one, would not the definition
    > >
    > > #define offsetof(TYPE,MEMBER) \
    > > ((size_t) ( \
    > > (char*) &((TYPE *)0)->MEMBER - (char*) &(*(TYPE *)0) \
    > > ))
    > >
    > >be more likely to yield more-portably correct results?

    >
    > Aside from the extra "&", this is the one in the comp.lang.c FAQ
    > (question 2.14).


    Ahh, I'd forgotten that. It makes sense though.


    > >Presumably if one definition invokes UB then the other does (and vice
    > >versa?). That notwithstanding, however (or alternatively, if one were
    > >writing 'offsetof()' as part of a C implementation), doesn't the
    > >subtractive definition seem a little cleaner than the earlier one?

    >
    > Implementors are, of course, allowed to be "arbitrarily dirty" since
    > they (presumably) control the horizontal and the vertical. Perhaps
    > offsetof() is #define'd as:
    >
    > #define offsetof(t, f) _O_O_(f, t)
    >
    > for instance. :) The subtractive version would in general remove
    > any "nonzero null pointer bias" that might be left behind without
    > the subtraction, but one would certainly hope that the implementor
    > knows how he implemented his null pointers.


    Right. I admit it's a fine distinction. It just seems like people
    would want to choose a definition that's more likely to work in the
    _next_ implementation; in fact I would expect the subtractive
    definition to work in any implementation unless the compiler made an
    effort to thwart it. Also the subtractive definition has educational
    value - it serves as a reminder that null pointers don't necessarily
    have the value zero, and we can expect that new C programmers will
    (occasionally) read definitions of 'offsetof()' and get that notion
    reinforced.

    Can you tell that I'm someone who believes in defensive safe
    coding practices? :)

    Thank you Chris for your comments.
    Tim Rentsch, Oct 24, 2004
    #16
    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. Lance Riedel

    Translated Offset to Source Offset

    Lance Riedel, Oct 14, 2003, in forum: XML
    Replies:
    2
    Views:
    485
    Patrick TJ McPhee
    Oct 15, 2003
  2. Replies:
    10
    Views:
    1,091
    Keith Thompson
    Jun 23, 2005
  3. gokrix

    Structure member offset.

    gokrix, Dec 2, 2005, in forum: C Programming
    Replies:
    10
    Views:
    619
    Richard Tobin
    Dec 2, 2005
  4. RAKHE

    OFFSET of Structure Member

    RAKHE, Jun 24, 2010, in forum: C Programming
    Replies:
    8
    Views:
    3,404
  5. Roy Smith
    Replies:
    4
    Views:
    240
    Roy Smith
    Jan 27, 2013
Loading...

Share This Page