Obtain sizeof struct element using offsetof()?

Discussion in 'C Programming' started by Mark A. Odell, Sep 27, 2004.

  1. Is there a way to obtain the size of a struct element based only upon its
    offset within the struct? I seem unable to figure out a way to do this
    (short of comparing every element's offset with <offset>). What I would
    like to do is create an API something like this:

    #include <stddef.h>

    struct MemMap
    {
    unsigned char apple; // 8 bits on my platform
    unsigned char butter;
    unsigned short pear; // 16 bits on my platform
    unsigned long peach; // 32 bits on my platform
    };

    static struct MemMap memMap;

    /* <offset> is the offset of the MemMap struct element
    ** that this function is to write with the appropriately
    ** sized value pointed to by <pVal>.
    */
    int writeMemMapReg(size_t offset, void *pVal)
    {
    int failures = 0;
    size_t size = /* sizeof element at <offset> */;
    unsigned char *p8Bits;
    unsigned short *p16Bits;
    unsigned long *p32Bits;

    switch (size)
    {
    case 1:
    p8Bits = (unsigned char *) pVal;
    /* somehow write *p8Bits to memMap struct at
    ** <offset>.
    */
    break;

    case 2:
    p16Bits = (unsigned short *) pVal;
    /* somehow write *p16Bits to memMap struct at
    ** <offset>.
    */
    break;

    case 4:
    p32Bits = (unsigned long *) pVal;
    /* somehow write *p32Bits to memMap struct at
    ** <offset>.
    */
    break;

    default:
    /* Error */
    failures = !0;
    break;
    }

    return failures;
    }

    Any help much appreciated.

    --
    - Mark ->
    --
     
    Mark A. Odell, Sep 27, 2004
    #1
    1. Advertising

  2. Mark A. Odell

    Eric Sosman Guest

    Mark A. Odell wrote:
    > Is there a way to obtain the size of a struct element based only upon its
    > offset within the struct? [...]


    No. Consider

    struct x { char cx; };
    struct y { char cy[100]; };

    Here, `offsetof(struct x, cx) == offsetof(struct y, cy)',
    yet the sizes of the `cx' and `cy' elements are different.
    No (legitimate) computation "based only" on the input value
    zero could produce both 1 and 100 as outputs.

    --
     
    Eric Sosman, Sep 27, 2004
    #2
    1. Advertising

  3. Eric Sosman <> wrote in
    news:cj9d6n$f6c$:

    > Mark A. Odell wrote:
    >> Is there a way to obtain the size of a struct element based only upon
    >> its offset within the struct? [...]

    >
    > No. Consider
    >
    > struct x { char cx; };
    > struct y { char cy[100]; };
    >
    > Here, `offsetof(struct x, cx) == offsetof(struct y, cy)',
    > yet the sizes of the `cx' and `cy' elements are different.
    > No (legitimate) computation "based only" on the input value
    > zero could produce both 1 and 100 as outputs.


    Of course. Thanks Eric. I guess I'll have to do some macro magic with some
    built in assumptions about the struct if I want to simplify the caller's
    interface.

    Regards.

    --
    - Mark ->
    --
     
    Mark A. Odell, Sep 27, 2004
    #3
  4. Mark A. Odell

    Dan Pop Guest

    In <Xns95716F8514343CopyrightMarkOdell@130.133.1.4> "Mark A. Odell" <> writes:

    >Is there a way to obtain the size of a struct element based only upon its
    >offset within the struct?


    Even if you also knew the offset of the next member that would be
    impossible, due to the padding between members.

    >I seem unable to figure out a way to do this
    >(short of comparing every element's offset with <offset>).


    Nothing wrong with this approach.

    >What I would like to do is create an API something like this:


    I can't imagine any practical need for that. You can also pass the
    type of the value, encoded using an ad hoc convention: the caller *must*
    know it. The callee now has all the information needed to know how to
    access the pointed data.

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
    Currently looking for a job in the European Union
     
    Dan Pop, Sep 27, 2004
    #4
  5. Eric Sosman wrote:
    > Mark A. Odell wrote:
    >
    >> Is there a way to obtain the size of a struct element based only upon its
    >> offset within the struct? [...]

    >
    > struct x { char cx; };
    > struct y { char cy[100]; };
    >
    > [ . . . ] No (legitimate) computation "based only" on the input value
    > zero could produce both 1 and 100 as outputs.


    That said, you can certainly calculate the size of each member of any
    struct using only offsetof and sizeof:
    sizeof(struct x) - offsetof(struct x, cx) == 1
    sizeof(struct x) - offsetof(struct x, cy) == 100
    It doesn't seem like you could gain much by doing this, though, unless
    you're creating some kind of metaprogramming tool.
    --
    Derrick Coetzee
    I grant this newsgroup posting into the public domain. I disclaim all
    express or implied warranty and all liability. I am not a professional.
     
    Derrick Coetzee, Sep 28, 2004
    #5
  6. Mark A. Odell

    xarax Guest

    "Mark A. Odell" <> wrote in message
    news:Xns95716F8514343CopyrightMarkOdell@130.133.1.4...
    > Is there a way to obtain the size of a struct element based only upon its
    > offset within the struct? I seem unable to figure out a way to do this
    > (short of comparing every element's offset with <offset>). What I would
    > like to do is create an API something like this:
    >
    > #include <stddef.h>
    >

    typedef unsigned char Apple_t;
    typedef unsigned char Butter_t;
    typedef unsigned short Pear_t;
    typedef unsigned long Peach_t;

    typedef struct mem_map
    {
    Apple_t apple;
    Butter_t butter;
    Pear_t pear;
    Peach_t peach;
    } MemMap;

    typedef enum mem_map_offsets
    {
    MemMapApple = offsetof(MemMap,apple),
    MemMapButter = offsetof(MemMap,butter),
    MemMapPear = offsetof(MemMap,pear),
    MemMapPeach = offsetof(MemMap,peach)
    } MemMapOffsets;

    static MemMap memMap;

    >
    > /* <offset> is the offset of the MemMap struct element
    > ** that this function is to write with the appropriately
    > ** sized value pointed to by <pVal>.
    > */

    int writeMemMapReg(MemMapOffsets offset, void *pVal)
    > {
    > int failures = 0;


    switch(offset)
    {
    case MemMapApple:
    memMap.apple = *(Apple_t *) pVal;
    break;

    case MemMapButter:
    memMap.butter = *(Butter_t *) pVal;
    break;

    case MemMapPear:
    memMap.pear = *(Pear_t *) pVal;
    break;

    case MemMapPeach:
    memMap.peach = *(Peach_t *) pVal;
    break;

    default:
    failures = 1;
    }

    >
    > return failures;
    > }
    >
    > Any help much appreciated.
    >
    > --
    > - Mark ->
    > --
     
    xarax, Sep 28, 2004
    #6
  7. Mark A. Odell

    j0mbolar Guest

    Derrick Coetzee <> wrote in message news:<cjaatr$ije$>...
    > Eric Sosman wrote:
    > > Mark A. Odell wrote:
    > >
    > >> Is there a way to obtain the size of a struct element based only upon its
    > >> offset within the struct? [...]

    > >
    > > struct x { char cx; };
    > > struct y { char cy[100]; };
    > >
    > > [ . . . ] No (legitimate) computation "based only" on the input value
    > > zero could produce both 1 and 100 as outputs.

    >
    > That said, you can certainly calculate the size of each member of any
    > struct using only offsetof and sizeof:
    > sizeof(struct x) - offsetof(struct x, cx) == 1
    > sizeof(struct x) - offsetof(struct x, cy) == 100
    > It doesn't seem like you could gain much by doing this, though, unless
    > you're creating some kind of metaprogramming tool.



    This is incorrect. If you have the following:

    struct foo {
    char cx;
    char cy[100];
    };

    then you can have padding after cy which is included in the size
    of the actual struct. so sizeof(struct foo) does not give you the
    size, in bytes, of the summation of all member sizes.
     
    j0mbolar, Sep 28, 2004
    #7
  8. "j0mbolar" <> wrote in message
    news:...

    > This is incorrect. If you have the following:
    >
    > struct foo {
    > char cx;
    > char cy[100];
    > };
    >
    > then you can have padding after cy which is included in the size
    > of the actual struct. so sizeof(struct foo) does not give you the


    Practically, there are no chances to have any paddings with this code.

    Instead, the following:

    struct foo {
    int i;
    char c;
    };

    certainly will have the tail one.
     
    Ivan A. Kosarev, Sep 28, 2004
    #8
  9. Mark A. Odell

    Dan Pop Guest

    In <cjaatr$ije$> Derrick Coetzee <> writes:

    >Eric Sosman wrote:
    >> Mark A. Odell wrote:
    >>
    >>> Is there a way to obtain the size of a struct element based only upon its
    >>> offset within the struct? [...]

    >>
    >> struct x { char cx; };
    >> struct y { char cy[100]; };
    >>
    >> [ . . . ] No (legitimate) computation "based only" on the input value
    >> zero could produce both 1 and 100 as outputs.

    >
    >That said, you can certainly calculate the size of each member of any
    >struct using only offsetof and sizeof:


    Can you?

    >sizeof(struct x) - offsetof(struct x, cx) == 1
    >sizeof(struct x) - offsetof(struct x, cy) == 100


    What about the padding the compiler can insert between any two members or
    at the end?

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
    Currently looking for a job in the European Union
     
    Dan Pop, Sep 28, 2004
    #9
  10. j0mbolar wrote:
    >>That said, you can certainly calculate the size of each member of any
    >>struct using only offsetof and sizeof:
    >>sizeof(struct x) - offsetof(struct x, cx) == 1
    >>sizeof(struct x) - offsetof(struct x, cy) == 100
    >>It doesn't seem like you could gain much by doing this, though, unless
    >>you're creating some kind of metaprogramming tool.

    >
    > This is incorrect. [ . . . ] you can have padding after cy which is included in the size
    > of the actual struct.


    I'm sorry, of course you're right. If you have an instance of the struct
    handy, though, you can always use sizeof directly on the elements:

    struct x {
    int a;
    char b;
    };

    int main() {
    struct x y;
    int c = sizeof(y.a);
    int d = sizeof(y.b);
    }

    --
    Derrick Coetzee
    I grant this newsgroup posting into the public domain. I disclaim all
    express or implied warranty and all liability. I am not a professional.
     
    Derrick Coetzee, Sep 28, 2004
    #10
  11. Groovy hepcat Derrick Coetzee was jivin' on Mon, 27 Sep 2004 20:22:52
    -0400 in comp.lang.c.
    Re: Obtain sizeof struct element using offsetof()?'s a cool scene! Dig
    it!

    >Eric Sosman wrote:
    >> Mark A. Odell wrote:
    >>
    >>> Is there a way to obtain the size of a struct element based only upon its
    >>> offset within the struct? [...]

    >>
    >> struct x { char cx; };
    >> struct y { char cy[100]; };
    >>
    >> [ . . . ] No (legitimate) computation "based only" on the input value
    >> zero could produce both 1 and 100 as outputs.

    >
    >That said, you can certainly calculate the size of each member of any
    >struct using only offsetof and sizeof:
    >sizeof(struct x) - offsetof(struct x, cx) == 1
    >sizeof(struct x) - offsetof(struct x, cy) == 100


    Nonsense! Assuming that you are referring to the struct x defined
    above, it does not have a cy member. And structures may have padding
    following any member, thus sizeof(struct x) - offsetof(struct x, cx)
    need not be equal to the size of the structure's only member. And, of
    course, if the struct has more than one member, then your equations
    are false anyhow.

    --

    Dig the even newer still, yet more improved, sig!

    http://alphalink.com.au/~phaywood/
    "Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
    I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
     
    Peter Shaggy Haywood, Oct 1, 2004
    #11
    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. Chris Fogelklou
    Replies:
    36
    Views:
    1,391
    Chris Fogelklou
    Apr 20, 2004
  2. Michael B Allen

    offsetof(struct foo, bar.mem)?

    Michael B Allen, Sep 2, 2005, in forum: C Programming
    Replies:
    3
    Views:
    616
    Peter Nilsson
    Sep 5, 2005
  3. Urs Thuermann
    Replies:
    6
    Views:
    2,024
    Harald van =?UTF-8?B?RMSzaw==?=
    May 25, 2007
  4. Not Really Me
    Replies:
    2
    Views:
    764
    Jack Klein
    Mar 14, 2008
  5. Maciej Labanowicz

    [TinyCC] sizeof of element of struct returned by function

    Maciej Labanowicz, Feb 20, 2013, in forum: C Programming
    Replies:
    18
    Views:
    349
    Anders Wegge Keller
    Feb 22, 2013
Loading...

Share This Page