structure address = structure first field address ?

V

Vincent De Groote

Hello,

Does the C89/c90 language asserts that the address of a structure and
the address of the first field of the structure are the same ?

Tnaks for your replies and your time

Vincent De Groote
 
E

Eric Sosman

Vincent said:
Hello,

Does the C89/c90 language asserts that the address of a structure and
the address of the first field of the structure are the same ?

Yes. More precisely, it states that you can convert
a pointer to the struct to a pointer of the first element's
type and use it to access the first element, or you can
convert a pointer to the first element to the struct's
type and use it to access the struct.
 
J

jameskuyper

Vincent said:
Hello,

Does the C89/c90 language asserts that the address of a structure and
the address of the first field of the structure are the same ?

The standard guarantees that "A pointer to a structure object,
suitably converted, points to its initial member (or if that member is
a bit-field, then to the unit in which it resides), and vice versa.
There may be unnamed
padding within a structure object, but not at its
beginning." (6.7.2.1p13)
 
K

kid joe

Hello,

Does the C89/c90 language asserts that the address of a structure and
the address of the first field of the structure are the same ?

Hi Vincent,

I think I can answer this one... No, I dont believe it does, because there
can be "padding bytes" inserted between fields of a struct, also at the
beginning and the end.

E.g. if the first field is a char and the second field is an int, the
compiler will fill out the struct so that the char is one of the bytes
in a full dword (or qword on 64bit) - and it could be any one of the bytes
(which one may depend on endianness of the machine?? but that's just a
guess).

Cheers,
Joe
 
C

CBFalconer

Vincent said:
Does the C89/c90 language asserts that the address of a structure
and the address of the first field of the structure are the same ?

Yes.
 
K

Keith Thompson

kid joe said:
I think I can answer this one... No, I dont believe it does, because there
can be "padding bytes" inserted between fields of a struct, also at the
beginning and the end.
[...]

No, that's incorrect. The standard very specifically does *not*
permit padding before the first member of a struct.
 
K

kid joe

kid joe said:
I think I can answer this one... No, I dont believe it does, because there
can be "padding bytes" inserted between fields of a struct, also at the
beginning and the end.
[...]

No, that's incorrect. The standard very specifically does *not*
permit padding before the first member of a struct.

Hi Keith,

Thanks for the correction.

I find that strange... if I was a compiler writer on an endianness where
the least-significant byte was at the top end of the word, my thought to
implement a struct with char followed by int, Id allocate a whole dword
for the char, just do native-width integer operations on the dword, then
access and set the char through an 0xFF mask. But it sounds like that
wouldnt be standards-compliant.

Cheers,
Joe


--

...................... o _______________ _,
` Good Afternoon! , /\_ _| | .-'_|
`................, _\__`[_______________| _| (_|
] [ \, ][ ][ (_|
 
K

Kenny McCormack

Hi Keith,

Thanks for the correction.[/QUOTE]

Please, sir. Could I have some more?
I find that strange... if I was a compiler writer on an endianness where
the least-significant byte was at the top end of the word, my thought to
implement a struct with char followed by int, Id allocate a whole dword
for the char, just do native-width integer operations on the dword, then
access and set the char through an 0xFF mask. But it sounds like that
wouldnt be standards-compliant.

The way it is usually done is to put the padding *before* the beginning
of the struct - i.e., so that the struct is aligned to the type of its
first element.
 
R

Richard Tobin

I find that strange... if I was a compiler writer on an endianness where
the least-significant byte was at the top end of the word,

.... and where there was no equally efficient instruction for accessing
the high-order byte...
my thought to
implement a struct with char followed by int, Id allocate a whole dword
for the char, just do native-width integer operations on the dword, then
access and set the char through an 0xFF mask. But it sounds like that
wouldnt be standards-compliant.

Correct. C's rules do not always permit the most efficient layout of
data. But there are other considerations in standardisation, such as
existing programs that rely on being able to convert the address of
a structure to the address of its first member.

Your case is probably not a common one.

-- Richard
 
B

Barry Schwarz

Hi Keith,

Thanks for the correction.

Please, sir. Could I have some more?
I find that strange... if I was a compiler writer on an endianness where
the least-significant byte was at the top end of the word, my thought to
implement a struct with char followed by int, Id allocate a whole dword
for the char, just do native-width integer operations on the dword, then
access and set the char through an 0xFF mask. But it sounds like that
wouldnt be standards-compliant.

The way it is usually done is to put the padding *before* the beginning
of the struct - i.e., so that the struct is aligned to the type of its
first element.[/QUOTE]

The structure must be aligned and padding inserted as needed
everywhere except before the first member so that every member is
properly aligned.
 
C

CBFalconer

Barry said:
(e-mail address removed) (Kenny McCormack) wrote:
.... snip ...


The structure must be aligned and padding inserted as needed
everywhere except before the first member so that every member
is properly aligned.

Bear in mind that McCormack is an admitted troll. From the C
standard:

7.20.3 Memory management functions

[#1] The order and contiguity of storage allocated by
successive calls to the calloc, malloc, and realloc
functions is unspecified. The pointer returned if the
allocation succeeds is suitably aligned so that it may be
assigned to a pointer to any type of object and then used to
access such an object or an array of such objects in the
space allocated (until the space is explicitly freed or
reallocated). Each such allocation shall yield a pointer to
an object disjoint from any other object. The pointer
returned points to the start (lowest byte address) of the
allocated space. If the space cannot be allocated, a null
pointer is returned. If the size of the space requested is
zero, the behavior is implementation-defined: either a null
pointer is returned, or the behavior is as if the size were
some nonzero value, except that the returned pointer shall
not be used to access an object. The value of a pointer
that refers to freed space is indeterminate.
 
B

Barry Schwarz

Barry said:
(e-mail address removed) (Kenny McCormack) wrote:
... snip ...


The structure must be aligned and padding inserted as needed
everywhere except before the first member so that every member
is properly aligned.

Bear in mind that McCormack is an admitted troll. From the C
standard:

7.20.3 Memory management functions

[#1] The order and contiguity of storage allocated by
successive calls to the calloc, malloc, and realloc
functions is unspecified. The pointer returned if the
allocation succeeds is suitably aligned so that it may be
assigned to a pointer to any type of object and then used to
access such an object or an array of such objects in the
space allocated (until the space is explicitly freed or
reallocated). Each such allocation shall yield a pointer to
an object disjoint from any other object. The pointer
returned points to the start (lowest byte address) of the
allocated space. If the space cannot be allocated, a null
pointer is returned. If the size of the space requested is
zero, the behavior is implementation-defined: either a null
pointer is returned, or the behavior is as if the size were
some nonzero value, except that the returned pointer shall
not be used to access an object. The value of a pointer
that refers to freed space is indeterminate.

The original post asked about defining structures, not allocating
space.
 
T

Tony

kid said:
Hi Vincent,

I think I can answer this one... No, I dont believe it does, because
there can be "padding bytes" inserted between fields of a struct,
also at the beginning and the end.

E.g. if the first field is a char and the second field is an int, the
compiler will fill out the struct so that the char is one of the bytes
in a full dword (or qword on 64bit) - and it could be any one of the
bytes (which one may depend on endianness of the machine?? but that's
just a guess).

I rely on the fact that the compiler gives some kind of padding/alignment
control, either via pragmas or commandline/IDE switches. I pretty much
byte-align everything (with the switch) and do "manual alignment" when
designing structs (not as hard as it sounds). The only real "gotcha" to
watch out for is pointer fields for their width is different on 32- and
64-bit platforms (put pointers at the top of the struct and subsequent field
will align nicely). I always use width-specified integral types.
 
K

Keith Thompson

Tony said:
I rely on the fact that the compiler gives some kind of padding/alignment
control, either via pragmas or commandline/IDE switches. I pretty much
byte-align everything (with the switch) and do "manual alignment" when
designing structs (not as hard as it sounds). The only real "gotcha" to
watch out for is pointer fields for their width is different on 32- and
64-bit platforms (put pointers at the top of the struct and subsequent field
will align nicely). I always use width-specified integral types.

Why? Is it really worth the effort to do manually what the compiler
would have done for you?
 
B

Beej Jorgensen

Golden California Girls said:
Or are you so daft as the think that the structure isn't aligned on the
correct boundary for its first element?

Typical CLC thread: 2 seconds of life followed by a solid 96-hour death
rattle.

-Beej
 
E

Eric Sosman

Beej said:
Typical CLC thread: 2 seconds of life followed by a solid 96-hour death
rattle.

Wrenching back towards topicality: The quoted statement
is only partially correct. A struct must be properly aligned
for *all* of its elements, not just for the first. This is
easily seen by considering an array s[] of structs containing
an element we'll call x: Since both s[0] and s[1] are aligned
to the struct's own needs and since both s[0].x and s[1].x are
aligned to the needs of x's type, it follows that the alignment
of the struct type is a multiple of the alignment of x's type.
Since we made no assumptions about which struct element x is,
nor about its firstness or lastness or offsetof nor anything
other than that it's some element of the struct, the same
argument holds for all elements.

Note that "multiple of" does not necessarily mean "smallest
multiple of," although it would be a fairly strange compiler
that didn't make it so.
 
B

Barry Schwarz

On Sat, 2 May 2009 01:38:27 -0700 (PDT),
but what he said made sense.

Just enough to be plausible. Unfortunately it was incomplete and not
quite accurate.
 
B

Barry Schwarz

Actually Kenny McCormack is 100% right. There may be padding before the

The proof that his statement is incorrect is simple. Consider a
system where int must be aligned on a multiple of 4 and long on a
multiple of 8. Now consider a struct on that system
struct s {int x; long y}z;

If z is located on a multiple of 8, then there must be 4 bytes of
padding between x and y (acutely 8k+4 for some non-negative k but I
would love to here about a system where k is not 0).

If z is located on an odd multiple of 4, there must be 0 bytes of
padding (actually 8k ...)

But the padding in z is not variable. Since either location satisfies
Kenny's statement but each requires a different amount of padding, the
statement cannot be correct.
structure. Or are you so daft as the think that the structure isn't aligned on
the correct boundary for its first element? As McCormack said very clearly that

The structure is actually aligned for all of its members and the issue
is usually driven by the member with the strictest requirement.
padding isn't considered part of the structure, never the less it is there!
Same thing happens when you get memory from malloc, but there it is talked about.

Now consider malloc in this system. It must return an address
suitable for any object. Since long must be on a multiple of 8,
malloc must return a multiple of 8. But since struct s is also an
object type, it must also be aligned on a multiple of 8 with four
bytes of padding since the address returned from malloc is suitable
for it also. Therefore again, z cannot be aligned on a multiple of 4
even though it satisfies Kenny's condition.
 

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

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top