Beginner C question

D

Der Engel

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;
}
 
D

Der Engel

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
 
I

Ian Collins

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).
 
N

Nobody

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.
 
K

Keith Thompson

Der Engel said:
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;
}
 
D

Der Engel

Der Engel said:
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) (e-mail address removed)  <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!
 
M

Michael Press

Der Engel said:
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.
 
I

Ian Collins

Der Engel said:
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.
 
M

Michael Press

Ian Collins said:
Der Engel said:
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.
 
S

Stephen Sprunk

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
 
M

Malcolm McLean

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.
 
K

Keith Thompson

Malcolm McLean said:
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?
 
M

Michael Press

Stephen Sprunk said:
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
 
B

Ben Pfaff

Michael Press said:
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.
 
M

Michael Press

Ben Pfaff said:
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.
 
M

Michael Press

Jonathan Leffler said:
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top