offset

Discussion in 'C Programming' started by henry, Dec 22, 2008.

  1. henry

    henry Guest

    List,

    Does offset mean size different between two structure members?
    I expect following output should be i=0,c=1,d=5 and a=6.

    But my x86 computer has output,

    offsets: i=0; c=4; d=8 a=16
    sizeof(struct s)=16

    #include <stddef.h>
    #include <stdio.h>
    #include <stdlib.h>
    int main()
    {
    struct s {
    int i;
    char c;
    double d;
    char a[];
    };
    /* Output is compiler dependent */

    printf("offsets: i=%ld; c=%ld; d=%ld a=%ld\n",
    (long) offsetof(struct s, i),
    (long) offsetof(struct s, c),
    (long) offsetof(struct s, d),
    (long) offsetof(struct s, a));
    printf("sizeof(struct s)=%ld\n", (long) sizeof(struct s));

    exit(EXIT_SUCCESS);
    }

    ---henry
     
    henry, Dec 22, 2008
    #1
    1. Advertising

  2. henry

    James Kuyper Guest

    henry wrote:
    > List,
    >
    > Does offset mean size different between two structure members?


    I'm not sure exactly what that question means. offsetof() gives a
    distance, not a size. Specifically, it's the number of bytes between the
    start of the specified structure and the start of the specified member
    of that structure.

    > I expect following output should be i=0,c=1,d=5 and a=6.


    You should explain how you reached those conclusions. They are not
    impossible, but are extremely unlikely.

    > But my x86 computer has output,
    >
    > offsets: i=0; c=4; d=8 a=16
    > sizeof(struct s)=16
    >
    > #include <stddef.h>
    > #include <stdio.h>
    > #include <stdlib.h>
    > int main()
    > {
    > struct s {
    > int i;
    > char c;
    > double d;
    > char a[];
    > };
    > /* Output is compiler dependent */
    >
    > printf("offsets: i=%ld; c=%ld; d=%ld a=%ld\n",
    > (long) offsetof(struct s, i),
    > (long) offsetof(struct s, c),
    > (long) offsetof(struct s, d),
    > (long) offsetof(struct s, a));
    > printf("sizeof(struct s)=%ld\n", (long) sizeof(struct s));
    >
    > exit(EXIT_SUCCESS);
    > }


    The only portable expectations you should have are as follows:

    offsetof(s,i) == 0
    offsetof(s,c) >= offsetof(s,i) + sizeof(int)
    offsetof(s,d) >= offsetof(s,c) + 1
    offsetof(s,a) >= offsetof(s,d) + sizeof(double)

    In practice, the first and third >= will probably be ==, but that's not
    required by the standard.
     
    James Kuyper, Dec 22, 2008
    #2
    1. Advertising

  3. henry wrote:
    > List,
    >
    > Does offset mean size different between two structure members?
    > I expect following output should be i=0,c=1,d=5 and a=6.


    That would be a truly bizarre system, though theoretically possible.
    I'm interested in why you expect those particular values.

    > But my x86 computer has output,
    >
    > offsets: i=0; c=4; d=8 a=16
    > sizeof(struct s)=16
    >
    > #include <stddef.h>
    > #include <stdio.h>
    > #include <stdlib.h>
    > int main()
    > {
    > struct s {
    > int i;
    > char c;
    > double d;
    > char a[];
    > };
    > /* Output is compiler dependent */
    >
    > printf("offsets: i=%ld; c=%ld; d=%ld a=%ld\n",
    > (long) offsetof(struct s, i),
    > (long) offsetof(struct s, c),
    > (long) offsetof(struct s, d),
    > (long) offsetof(struct s, a));
    > printf("sizeof(struct s)=%ld\n", (long) sizeof(struct s));
    >
    > exit(EXIT_SUCCESS);
    > }


    This program is actually pretty good; it does exactly what I think
    you're expecting it to. So, the question becomes, why does it give the
    values it does?

    When the compiler lays out a struct in memory, it is required to lay out
    the elements in order, with zero or more bytes of padding after each
    element. Since you mention x86, I'll assume the following values:

    sizeof(int)==4
    sizeof(double)==8

    sizeof(char) is always 1, and "a" is a flexible array member which has
    an effective size of 0, but we'll ignore that for now and pretend its
    size is also 1. So, we have a structure that looks like this in memory:

    iiii.c.dddddddd.a.

    where the dots represent possible padding. Why is there padding, and
    how does the compiler decide how much, if any, to insert? Well, many
    CPUs require that data be aligned properly, or at least run slower if it
    isn't, so padding keeps the data aligned. For 32-bit system like x86,
    this is most easily visualized (IMHO) by looking at memory in 4- or
    8-byte rows; without padding, your struct would be laid out like this:

    iiii
    cddd or iiiicddd
    dddd ddddddda
    ddda

    The CPU won't like d's misalignment, so padding is inserted, perhaps
    like this:

    iiii
    c... iiiic...
    dddd or dddddddd
    dddd a.......
    a...

    These offsets (0, 4, 8, 16) match the ones that your program produces.

    Now, if you count those bytes, you'll see the total size has expanded to
    20 or 24 bytes -- but remember a flexible array member's size is
    effectively zero, not one as we pretended above, so the struct actually
    looks like this:

    iiii
    c... or iiiic...
    dddd dddddddd
    dddd

    This size (16) matches the total size that your program produces.

    S
     
    Stephen Sprunk, Dec 22, 2008
    #3
  4. henry

    James Kuyper Guest

    Gordon Burditt wrote:
    >> Does offset mean size different between two structure members?

    >
    > No. The offset is the address difference between the member and
    > the beginning of the structure in bytes.
    >
    >> I expect following output should be i=0,c=1,d=5 and a=6.

    >
    > Why on earth would you expect that? Particularly strange is the
    > c=1 where the first element of the structure is an int. Yes, it's
    > POSSIBLE, but rather wierd. You seem to be expecting sizeof(int)
    > == 1 and sizeof(char) == 4, which is not permitted by the standard.


    His numbers could be produced by a perfectly conforming implementation
    where sizeof(int) == 1, sizeof(double) == 1, and for some bizarre reason
    the compiler decided to insert three bytes of padding between c and d. I
    doubt that this is his reason for expecting those numbers, however.

    >> But my x86 computer has output,
    >>
    >> offsets: i=0; c=4; d=8 a=16
    >> sizeof(struct s)=16
    >>
    >> #include <stddef.h>
    >> #include <stdio.h>
    >> #include <stdlib.h>
    >> int main()
    >> {
    >> struct s {
    >> int i;
    >> char c;
    >> double d;
    >> char a[];
    >> };
    >> /* Output is compiler dependent */
    >>
    >> printf("offsets: i=%ld; c=%ld; d=%ld a=%ld\n",
    >> (long) offsetof(struct s, i),
    >> (long) offsetof(struct s, c),
    >> (long) offsetof(struct s, d),
    >> (long) offsetof(struct s, a));
    >> printf("sizeof(struct s)=%ld\n", (long) sizeof(struct s));
    >>
    >> exit(EXIT_SUCCESS);
    >> }
     
    James Kuyper, Dec 22, 2008
    #4
  5. henry

    CBFalconer Guest

    henry wrote:
    >
    > Does offset mean size different between two structure members?
    > I expect following output should be i=0,c=1,d=5 and a=6.
    > But my x86 computer has output,
    >
    > offsets: i=0; c=4; d=8 a=16
    > sizeof(struct s)=16
    >
    > #include <stddef.h>
    > #include <stdio.h>
    > #include <stdlib.h>
    > int main() {
    > struct s {
    > int i;
    > char c;
    > double d;
    > char a[];
    > };
    > /* Output is compiler dependent */
    > printf("offsets: i=%ld; c=%ld; d=%ld a=%ld\n",
    > (long) offsetof(struct s, i),
    > (long) offsetof(struct s, c),
    > (long) offsetof(struct s, d),
    > (long) offsetof(struct s, a));
    > printf("sizeof(struct s)=%ld\n", (long) sizeof(struct s));
    > exit(EXIT_SUCCESS);
    > }


    Note that you have specified an empty array of char for a. This
    doesn't trigger an error here, even though I am using -ansi
    -pedantic -W -Wall on gcc 3.2.1 to use C90. Note the difference if
    you make that part of the struct definition read "char a;" or "char
    a[1];"

    offsets: i=0; c=4; d=8 a=16
    sizeof(struct s)=20

    --
    [mail]: Chuck F (cbfalconer at maineline dot net)
    [page]: <http://cbfalconer.home.att.net>
    Try the download section.
     
    CBFalconer, Dec 22, 2008
    #5
  6. henry

    James Kuyper Guest

    CBFalconer wrote:
    > henry wrote:

    ....
    >> #include <stddef.h>
    >> #include <stdio.h>
    >> #include <stdlib.h>
    >> int main() {
    >> struct s {
    >> int i;
    >> char c;
    >> double d;
    >> char a[];
    >> };
    >> /* Output is compiler dependent */
    >> printf("offsets: i=%ld; c=%ld; d=%ld a=%ld\n",
    >> (long) offsetof(struct s, i),
    >> (long) offsetof(struct s, c),
    >> (long) offsetof(struct s, d),
    >> (long) offsetof(struct s, a));
    >> printf("sizeof(struct s)=%ld\n", (long) sizeof(struct s));
    >> exit(EXIT_SUCCESS);
    >> }

    >
    > Note that you have specified an empty array of char for a. This
    > doesn't trigger an error here, even though I am using -ansi
    > -pedantic -W -Wall on gcc 3.2.1 to use C90.


    I've got gcc 4.1.2; it does produce the required diagnostic message when
    invoked with those options:

    warning: ISO C90 does not support flexible array members

    Note to OP: while flexible array members are constraint violations in
    C90, they are perfectly acceptable in C99.
     
    James Kuyper, Dec 23, 2008
    #6
    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. Maxim S. Lee

    How can I control UTC offset?

    Maxim S. Lee, Oct 16, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    539
    Dino Chiesa [Microsoft]
    Oct 27, 2004
  2. Replies:
    0
    Views:
    315
  3. Buddy Ackerman

    Getting local client UTC offset

    Buddy Ackerman, May 11, 2005, in forum: ASP .Net
    Replies:
    0
    Views:
    538
    Buddy Ackerman
    May 11, 2005
  4. Lance Riedel

    Translated Offset to Source Offset

    Lance Riedel, Oct 14, 2003, in forum: XML
    Replies:
    2
    Views:
    503
    Patrick TJ McPhee
    Oct 15, 2003
  5. Roy Smith
    Replies:
    4
    Views:
    277
    Roy Smith
    Jan 27, 2013
Loading...

Share This Page