Beginner C question

Discussion in 'C Programming' started by Der Engel, Apr 14, 2011.

  1. Der Engel

    Der Engel Guest

    Hi,

    Why does the following code returns 28 in a i386 machine and 32 in a
    amd64 machine? I guess this is more of a implementation/machine
    question.


    #include <stdio.h>

    struct flex
    {
    int count;
    double average;
    double scores[2];
    };

    int main(void)
    {
    printf("%zd\n", sizeof (struct flex));
    return 0;
    }
    Der Engel, Apr 14, 2011
    #1
    1. Advertising

  2. Der Engel

    Der Engel Guest

    On Apr 13, 8:22 pm, Der Engel <> wrote:
    > Hi,
    >
    > Why does the following code returns 28 in a i386 machine and 32 in a
    > amd64 machine? I guess this is more of a implementation/machine
    > question.
    >
    > #include <stdio.h>
    >
    > struct flex
    > {
    >     int count;
    >     double average;
    >     double scores[2];
    >
    > };
    >
    > int main(void)
    > {
    >     printf("%zd\n", sizeof (struct flex));
    >     return 0;
    >
    > }


    I must have said prints not returns.

    Thanks
    Der Engel, Apr 14, 2011
    #2
    1. Advertising

  3. Der Engel

    Ian Collins Guest

    On 04/14/11 01:22 PM, Der Engel wrote:
    > Hi,
    >
    > Why does the following code returns 28 in a i386 machine and 32 in a
    > amd64 machine? I guess this is more of a implementation/machine
    > question.
    >
    >
    > #include<stdio.h>
    >
    > struct flex
    > {
    > int count;
    > double average;
    > double scores[2];
    > };
    >
    > int main(void)
    > {
    > printf("%zd\n", sizeof (struct flex));
    > return 0;
    > }


    Alignment requirement of double (4 bytes on one, 8 on the other).

    --
    Ian Collins
    Ian Collins, Apr 14, 2011
    #3
  4. Der Engel

    Nobody Guest

    On Wed, 13 Apr 2011 18:22:51 -0700, Der Engel wrote:

    > Why does the following code returns 28 in a i386 machine and 32 in a
    > amd64 machine?


    It's almost certainly because the 64-bit system aligns doubles to an
    8-byte (64-bit) boundary while the 32-bit system aligns them to a 4-byte
    (32-bit) boundary, meaning that the 64-bit system has 4 bytes of padding
    between "count" and "average".

    There are other possible explanations, but the above is 99% likely to be
    what's actually happening.

    You can confirm this with e.g.:

    struct flex f;
    printf("%d\n", (int)((char*)f.average - (char*)f.count));

    > I guess this is more of a implementation/machine question.


    Yes. The C language doesn't dictate such details, allowing each
    implementation to do whatever is most efficient for the hardware.
    Nobody, Apr 14, 2011
    #4
  5. Der Engel <> writes:
    > Why does the following code returns 28 in a i386 machine and 32 in a
    > amd64 machine? I guess this is more of a implementation/machine
    > question.
    >
    >
    > #include <stdio.h>
    >
    > struct flex
    > {
    > int count;
    > double average;
    > double scores[2];
    > };
    >
    > int main(void)
    > {
    > printf("%zd\n", sizeof (struct flex));
    > return 0;
    > }


    Try this; it shows the sizes and offsets of all the members of the
    struct.

    Note that you should be using "%zu", not "%zd", since size_t is an
    unsigned type.

    #include <stdio.h>
    #include <stddef.h>

    struct flex
    {
    int count;
    double average;
    double scores[2];
    };

    int main(void)
    {
    struct flex f;
    printf("sizeof (struct flex) = %zu\n", sizeof (struct flex));
    printf("sizeof f = %zu (should be the same)\n", sizeof f);
    printf("f.count is %2zu bytes at offset %2zu\n",
    sizeof f.count, offsetof(struct flex, count));
    printf("f.average is %2zu bytes at offset %2zu\n",
    sizeof f.average, offsetof(struct flex, average));
    printf("f.scores is %2zu bytes at offset %2zu\n",
    sizeof f.scores, offsetof(struct flex, scores));
    printf("f.scores[0] is %2zu bytes at offset %2zu\n",
    sizeof f.scores[0], offsetof(struct flex, scores[0]));
    printf("f.scores[1] is %2zu bytes at offset %2zu\n",
    sizeof f.scores[1], offsetof(struct flex, scores[1]));
    return 0;
    }

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Apr 14, 2011
    #5
  6. Der Engel

    Der Engel Guest

    On Apr 14, 10:15 am, Keith Thompson <> wrote:
    > Der Engel <> writes:
    > > Why does the following code returns 28 in a i386 machine and 32 in a
    > > amd64 machine? I guess this is more of a implementation/machine
    > > question.

    >
    > > #include <stdio.h>

    >
    > > struct flex
    > > {
    > >     int count;
    > >     double average;
    > >     double scores[2];
    > > };

    >
    > > int main(void)
    > > {
    > >     printf("%zd\n", sizeof (struct flex));
    > >     return 0;
    > > }

    >
    > Try this; it shows the sizes and offsets of all the members of the
    > struct.
    >
    > Note that you should be using "%zu", not "%zd", since size_t is an
    > unsigned type.
    >
    > #include <stdio.h>
    > #include <stddef.h>
    >
    > struct flex
    > {
    >     int count;
    >     double average;
    >     double scores[2];
    >
    > };
    >
    > int main(void)
    > {
    >     struct flex f;
    >     printf("sizeof (struct flex) = %zu\n", sizeof (struct flex));
    >     printf("sizeof f = %zu (should be the same)\n", sizeof f);
    >     printf("f.count     is %2zu bytes at offset %2zu\n",
    >            sizeof f.count, offsetof(struct flex, count));
    >     printf("f.average   is %2zu bytes at offset %2zu\n",
    >            sizeof f.average, offsetof(struct flex, average));
    >     printf("f.scores    is %2zu bytes at offset %2zu\n",
    >            sizeof f.scores, offsetof(struct flex, scores));
    >     printf("f.scores[0] is %2zu bytes at offset %2zu\n",
    >            sizeof f.scores[0], offsetof(struct flex, scores[0]));
    >     printf("f.scores[1] is %2zu bytes at offset %2zu\n",
    >            sizeof f.scores[1], offsetof(struct flex, scores[1]));
    >     return 0;
    >
    > }
    >
    > --
    > Keith Thompson (The_Other_Keith)  <http://www.ghoti.net/~kst>
    > Nokia
    > "We must do something.  This is something.  Therefore, we must do this."
    >     -- Antony Jay and Jonathan Lynn, "Yes Minister"- Hide quoted text-
    >
    > - Show quoted text -


    Thank you all for you answers!
    Der Engel, Apr 14, 2011
    #6
  7. In article
    <>,
    Der Engel <> wrote:

    > Hi,
    >
    > Why does the following code returns 28 in a i386 machine and 32 in a
    > amd64 machine? I guess this is more of a implementation/machine
    > question.
    >
    >
    > #include <stdio.h>
    >
    > struct flex
    > {
    > int count;
    > double average;
    > double scores[2];
    > };
    >
    > int main(void)
    > {
    > printf("%zd\n", sizeof (struct flex));
    > return 0;
    > }


    I guess that the amd64 machine has sizeof(int) == 8,
    and the i386 machine has sizeof(int) == 4.

    --
    Michael Press
    Michael Press, Apr 17, 2011
    #7
  8. Der Engel

    Ian Collins Guest

    On 04/17/11 02:54 PM, Michael Press wrote:
    > In article
    > <>,
    > Der Engel<> wrote:
    >
    >> Hi,
    >>
    >> Why does the following code returns 28 in a i386 machine and 32 in a
    >> amd64 machine? I guess this is more of a implementation/machine
    >> question.
    >>
    >>
    >> #include<stdio.h>
    >>
    >> struct flex
    >> {
    >> int count;
    >> double average;
    >> double scores[2];
    >> };
    >>
    >> int main(void)
    >> {
    >> printf("%zd\n", sizeof (struct flex));
    >> return 0;
    >> }

    >
    > I guess that the amd64 machine has sizeof(int) == 8,
    > and the i386 machine has sizeof(int) == 4.


    You are probably wrong.

    --
    Ian Collins
    Ian Collins, Apr 17, 2011
    #8
  9. In article <>,
    Ian Collins <> wrote:

    > On 04/17/11 02:54 PM, Michael Press wrote:
    > > In article
    > > <>,
    > > Der Engel<> wrote:
    > >
    > >> Hi,
    > >>
    > >> Why does the following code returns 28 in a i386 machine and 32 in a
    > >> amd64 machine? I guess this is more of a implementation/machine
    > >> question.
    > >>
    > >>
    > >> #include<stdio.h>
    > >>
    > >> struct flex
    > >> {
    > >> int count;
    > >> double average;
    > >> double scores[2];
    > >> };
    > >>
    > >> int main(void)
    > >> {
    > >> printf("%zd\n", sizeof (struct flex));
    > >> return 0;
    > >> }

    > >
    > > I guess that the amd64 machine has sizeof(int) == 8,
    > > and the i386 machine has sizeof(int) == 4.

    >
    > You are probably wrong.


    Would not be the first time.

    --
    Michael Press
    Michael Press, Apr 17, 2011
    #9
  10. Der Engel

    Ian Collins Guest

    On 04/17/11 03:08 PM, Michael Press wrote:
    > In article<>,
    > Ian Collins<> wrote:
    >
    >> On 04/17/11 02:54 PM, Michael Press wrote:
    >>>
    >>> I guess that the amd64 machine has sizeof(int) == 8,
    >>> and the i386 machine has sizeof(int) == 4.

    >>
    >> You are probably wrong.

    >
    > Would not be the first time.


    :)

    I know the feeling!

    --
    Ian Collins
    Ian Collins, Apr 17, 2011
    #10
  11. On 16-Apr-11 21:54, Michael Press wrote:
    > I guess that the amd64 machine has sizeof(int) == 8,
    > and the i386 machine has sizeof(int) == 4.


    An ILP64 implementation on amd64 would be legal, but I've never heard of
    one; Linux et al are I32LP64 and Windows is IL32LLP64.

    (ILP64 means "short" has to be either 16- or 32-bit, leaving no native
    type for the other size. Plus, it tends to break bad (but common) code
    that assumes ILP32. I32LP64 is less problematic in practice.)

    S

    --
    Stephen Sprunk "God does not play dice." --Albert Einstein
    CCIE #3723 "God is an inveterate gambler, and He throws the
    K5SSS dice at every possible opportunity." --Stephen Hawking
    Stephen Sprunk, Apr 17, 2011
    #11
  12. On Apr 17, 5:54 am, Michael Press <> wrote:
    >
    > I guess that the amd64 machine has sizeof(int) == 8,
    > and the i386 machine has sizeof(int) == 4.
    >

    The campaign for 64 bit ints is trying to make 64 bits the standard
    for machines where the natural register or integer size if 64 bits.
    Malcolm McLean, Apr 17, 2011
    #12
  13. Malcolm McLean <> writes:
    > On Apr 17, 5:54 am, Michael Press <> wrote:
    >> I guess that the amd64 machine has sizeof(int) == 8,
    >> and the i386 machine has sizeof(int) == 4.
    >>

    > The campaign for 64 bit ints is trying to make 64 bits the standard
    > for machines where the natural register or integer size if 64 bits.


    Does this campaign have any members other than you?

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Apr 17, 2011
    #13
  14. In article <ioev9i$lqf$>,
    Stephen Sprunk <> wrote:

    > On 16-Apr-11 21:54, Michael Press wrote:
    > > I guess that the amd64 machine has sizeof(int) == 8,
    > > and the i386 machine has sizeof(int) == 4.

    >
    > An ILP64 implementation on amd64 would be legal, but I've never heard of
    > one; Linux et al are I32LP64 and Windows is IL32LLP64.
    >
    > (ILP64 means "short" has to be either 16- or 32-bit, leaving no native
    > type for the other size. Plus, it tends to break bad (but common) code
    > that assumes ILP32. I32LP64 is less problematic in practice.)


    OK. I found and read an article from 1998 that talks
    about this. It is not easy to shift from what is common
    today. One is all that code out there that assumes a
    pointer is the same width as an int.

    Datatype LP64 ILP64 LLP64 ILP32 LP32
    char 8 8 8 8 8
    short 16 16 16 16 16
    _int32 32
    int 32 64 32 32 16
    long 64 64 32 32 32
    long long 64
    pointer 64 64 64 32 32

    --
    Michael Press
    Michael Press, Apr 19, 2011
    #14
  15. Der Engel

    Ben Pfaff Guest

    Michael Press <> writes:

    > In article <ioev9i$lqf$>,
    > Stephen Sprunk <> wrote:
    >
    >> On 16-Apr-11 21:54, Michael Press wrote:
    >> > I guess that the amd64 machine has sizeof(int) == 8,
    >> > and the i386 machine has sizeof(int) == 4.

    >>
    >> An ILP64 implementation on amd64 would be legal, but I've never heard of
    >> one; Linux et al are I32LP64 and Windows is IL32LLP64.
    >>
    >> (ILP64 means "short" has to be either 16- or 32-bit, leaving no native
    >> type for the other size. Plus, it tends to break bad (but common) code
    >> that assumes ILP32. I32LP64 is less problematic in practice.)

    >
    > OK. I found and read an article from 1998 that talks
    > about this. It is not easy to shift from what is common
    > today. One is all that code out there that assumes a
    > pointer is the same width as an int.


    I run into more code that assumes that a pointer is the same
    width as a long. I guess the former is the "all the world is
    Windows" assumption and the latter is the "all the world is Unix"
    assumption.
    --
    Ben Pfaff
    http://benpfaff.org
    Ben Pfaff, Apr 19, 2011
    #15
  16. In article <>,
    Ben Pfaff <> wrote:

    > Michael Press <> writes:
    >
    > > In article <ioev9i$lqf$>,
    > > Stephen Sprunk <> wrote:
    > >
    > >> On 16-Apr-11 21:54, Michael Press wrote:
    > >> > I guess that the amd64 machine has sizeof(int) == 8,
    > >> > and the i386 machine has sizeof(int) == 4.
    > >>
    > >> An ILP64 implementation on amd64 would be legal, but I've never heard of
    > >> one; Linux et al are I32LP64 and Windows is IL32LLP64.
    > >>
    > >> (ILP64 means "short" has to be either 16- or 32-bit, leaving no native
    > >> type for the other size. Plus, it tends to break bad (but common) code
    > >> that assumes ILP32. I32LP64 is less problematic in practice.)

    > >
    > > OK. I found and read an article from 1998 that talks
    > > about this. It is not easy to shift from what is common
    > > today. One is all that code out there that assumes a
    > > pointer is the same width as an int.

    >
    > I run into more code that assumes that a pointer is the same
    > width as a long. I guess the former is the "all the world is
    > Windows" assumption and the latter is the "all the world is Unix"
    > assumption.


    Most of my limited experience is with UNIX &
    the like, but is not worth considering; so I
    could as well have mentioned code that assumes
    pointers are the same width as long.

    --
    Michael Press
    Michael Press, Apr 21, 2011
    #16
  17. In article <>,
    Jonathan Leffler <> wrote:

    > On 4/19/11 2:27 PM, Michael Press wrote:
    > > In article<ioev9i$lqf$>,
    > > Stephen Sprunk<> wrote:
    > >
    > >> On 16-Apr-11 21:54, Michael Press wrote:
    > >>> I guess that the amd64 machine has sizeof(int) == 8,
    > >>> and the i386 machine has sizeof(int) == 4.
    > >>
    > >> An ILP64 implementation on amd64 would be legal, but I've never heard of
    > >> one; Linux et al are I32LP64 and Windows is IL32LLP64.
    > >>
    > >> (ILP64 means "short" has to be either 16- or 32-bit, leaving no native
    > >> type for the other size. Plus, it tends to break bad (but common) code
    > >> that assumes ILP32. I32LP64 is less problematic in practice.)

    > >
    > > OK. I found and read an article from 1998 that talks
    > > about this. It is not easy to shift from what is common
    > > today. One is all that code out there that assumes a
    > > pointer is the same width as an int.
    > >
    > > Datatype LP64 ILP64 LLP64 ILP32 LP32
    > > char 8 8 8 8 8
    > > short 16 16 16 16 16
    > > _int32 32
    > > int 32 64 32 32 16
    > > long 64 64 32 32 32
    > > long long 64
    > > pointer 64 64 64 32 32
    > >

    >
    > I think there are problems with the table above - superficially, it
    > looks as though the column labelled LP64 is illustrating ILP64 and the
    > column labelled ILP64 is illustrating LP64. The entry with '_int32'
    > should probably be one column earlier; it is not clear that the name for
    > the row starting 'int 32' is felicitous since it shows 64-bit and 16-bit
    > ints.
    >
    > There also seems to be a similar mislabelling of the ILP32 and LP32...
    >
    > ...Oh, unless the 'int 32' line is simply mis-indented!
    >
    > It's interesting that the table doesn't designate the size of 'long
    > long' in the other columns - in particular, LLP64 should have 64 in the
    > 'long long' column.
    >
    > Data type | LP64 | ILP64 | LLP64 | ILP32 | LP32
    > char | 8 | 8 | 8 | 8 | 8
    > short | 16 | 16 | 16 | 16 | 16
    > _int32 | | 32 | | |
    > int | 32 | 64 | 32 | 32 | 16
    > long | 64 | 64 | 32 | 32 | 32
    > long long | 64 | 64 | 64 | 64 | 64
    > pointer | 64 | 64 | 64 | 32 | 32
    >
    > If viewed with a variable-width font, that may still look screwy. The
    > pipe symbols were added in an attempt to help.


    Apologies.
    Uncritical copy and paste from a document on the web.

    --
    Michael Press
    Michael Press, Apr 22, 2011
    #17
    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. Jerker Hammarberg

    Beginner question: What trigs processes

    Jerker Hammarberg, Jul 17, 2003, in forum: VHDL
    Replies:
    16
    Views:
    1,621
    Mike Treseler
    Jul 22, 2003
  2. smu
    Replies:
    3
    Views:
    2,634
    shobhit24
    Jun 28, 2006
  3. =?Utf-8?B?S3VydCBTY2hyb2VkZXI=?=

    No Class at ALL!!! beginner/beginner question

    =?Utf-8?B?S3VydCBTY2hyb2VkZXI=?=, Feb 2, 2005, in forum: ASP .Net
    Replies:
    7
    Views:
    570
    =?Utf-8?B?S3VydCBTY2hyb2VkZXI=?=
    Feb 3, 2005
  4. Rensjuh
    Replies:
    7
    Views:
    964
    Mabden
    Sep 2, 2004
  5. william nelson

    Beginner's Beginner

    william nelson, Apr 11, 2011, in forum: Ruby
    Replies:
    7
    Views:
    211
    7stud --
    Apr 12, 2011
Loading...

Share This Page