Please explain the output

K

Keith Thompson

Tim Rentsch said:
Kenneth Brody said:
Suppose you had this:

struct foo
{
char str[4];
int i;
}
c = { "abc" };

...

int *i = (int *)c.str;

Doesn't the standard guarantee that the struct be aligned in such a
way that c.str (the first struct element) must be properly aligned for
an int?

Yes, the alignment requirements for a struct are at least as
restrictive as the alignment requirements for each of the
members of the struct; this implication must hold because
of the guarantees made by malloc(). The alignment of the
first struct element matches the alignment of the struct,
as you point out.

I think it's true that the alignment requirements for a struct are at
least as restrictive as the alignment requirements for each of the
members, but this isn't implies by malloc(). A declared object
needn't be as strictly aligned as one allocated by malloc(). The
restriction follows from the requirements that all the members have to
be properly aligned, however the struct object itself was allocated.
 
T

Tim Rentsch

Keith Thompson said:
Tim Rentsch said:
Kenneth Brody said:
Suppose you had this:

struct foo
{
char str[4];
int i;
}
c = { "abc" };

...

int *i = (int *)c.str;

Doesn't the standard guarantee that the struct be aligned in such a
way that c.str (the first struct element) must be properly aligned for
an int?

Yes, the alignment requirements for a struct are at least as
restrictive as the alignment requirements for each of the
members of the struct; this implication must hold because
of the guarantees made by malloc(). The alignment of the
first struct element matches the alignment of the struct,
as you point out.

I think it's true that the alignment requirements for a struct are at
least as restrictive as the alignment requirements for each of the
members, but this isn't implies by malloc(). A declared object
needn't be as strictly aligned as one allocated by malloc(). The
restriction follows from the requirements that all the members have to
be properly aligned, however the struct object itself was allocated.

What I said was the implication must hold because of guarantees made
by malloc(), not that the storage needs to be malloc()'ed for the
implication to hold. Consider the following struct:

struct short_int_short {
short a;
int b;
short c;
};

Suppose sizeof(short) == 2 and sizeof(int) == 4, and these numbers are
also the respective alignments. If being able to malloc() the struct
weren't a consideration, this struct (with no internal padding) could
be aligned to an address that is equal to 2 mod 4. But, since we must
be able to use malloc() to allocate the struct, that set of padding
and alignment requirements doesn't work. So it's only because of the
guarantees made by malloc() that the implication follows.
 
K

Keith Thompson

Tim Rentsch said:
Keith Thompson said:
Tim Rentsch said:
[snip]
Suppose you had this:

struct foo
{
char str[4];
int i;
}
c = { "abc" };

...

int *i = (int *)c.str;

Doesn't the standard guarantee that the struct be aligned in such a
way that c.str (the first struct element) must be properly aligned for
an int?

Yes, the alignment requirements for a struct are at least as
restrictive as the alignment requirements for each of the
members of the struct; this implication must hold because
of the guarantees made by malloc(). The alignment of the
first struct element matches the alignment of the struct,
as you point out.

I think it's true that the alignment requirements for a struct are at
least as restrictive as the alignment requirements for each of the
members, but this isn't implies by malloc(). A declared object
needn't be as strictly aligned as one allocated by malloc(). The
restriction follows from the requirements that all the members have to
be properly aligned, however the struct object itself was allocated.

What I said was the implication must hold because of guarantees made
by malloc(), not that the storage needs to be malloc()'ed for the
implication to hold. Consider the following struct:

struct short_int_short {
short a;
int b;
short c;
};

Suppose sizeof(short) == 2 and sizeof(int) == 4, and these numbers are
also the respective alignments. If being able to malloc() the struct
weren't a consideration, this struct (with no internal padding) could
be aligned to an address that is equal to 2 mod 4. But, since we must
be able to use malloc() to allocate the struct, that set of padding
and alignment requirements doesn't work. So it's only because of the
guarantees made by malloc() that the implication follows.

Hmm. I think you're right (but that's no guarantee of anything). I
had actually written something about 2 mod 4 alignment in my previous
followup, but I deleted it before posting.

My thought was that 2 mod 4 alignment is implicitly forbidden by the
requirement to support arrays of structs with no padding between
elements. But as long as the size of the struct is a multiple of 4,
arrays would still work. Assuming sizeof(short)==2, sizeof(int)==4,
and sizeof(struct short_int_short)==8, the elements of an array
of struct short_int_short could be allocated at addresses (shown
in decimal):
1002
1010
1018
1026
...

But since a malloc()ed block of storage has to be aligned for type int
*and* for type struct short_int_short, the alignments of those two
types (and of any two object types) has to be compatible.

It looks like array requrements *don't* forbid 2 mod 4 alignment (I
thought they did), but the malloc() requirements do (I thought they
didn't).
 

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,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top