Re: Pre-offsetof() question
From: Eric Sosman (Eric.Sosman_at_sun.com)
Date: 10/06/03
- Next message: Robert J. Kolker: "Re: Fundamental Reason for High Achievements of Jews"
- Previous message: Mike Wahler: "Re: [OT, welcome msg, link, redir] linux kernel system call"
- In reply to: Arthur J. O'Dwyer: "Pre-offsetof() question"
- Next in thread: Arthur J. O'Dwyer: "Re: Pre-offsetof() question"
- Reply: Arthur J. O'Dwyer: "Re: Pre-offsetof() question"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Mon, 06 Oct 2003 16:26:40 -0400
"Arthur J. O'Dwyer" wrote:
>
> As far as I know, C89/C90 did not contain the
> now-standard offsetof() macro.
Full stop: C89 invented the <stddef.h> header, and specified
that it must provide offsetof().
> Did C89 mandate that structs had to have a consistent
> layout? For example, consider the typical layout of
> the following structure:
>
> struct weird
> {
> int x; /* sizeof(int)==4 here */
> double y; /* sizeof(double)==8 here */
> int z;
> };
>
> Now, let's suppose that the target architecture has typical
> 80x86 alignment requirements, where 'int' aligns on 4-byte
> boundaries and 'double' on 8-byte boundaries.
> A C99 compiler might produce a layout that looked like
> this:
>
> |_x__|####|___y____|_z__|####|
>
> sizeof (struct weird) == 24 bytes
>
> But could a C89, pre-offsetof() compiler decide to make
> the layout of the struct vary, like this:
>
> |_x__|####|___y____|_z__| on 8-byte alignment
>
> |_x__|___y____|####|_z__| on 4-byte alignment
>
> sizeof (struct weird) == 20 bytes
>
> Note that the relative ordering of the members is
> preserved; each 'struct weird' has the same size in
> bytes; and all objects are properly aligned for their
> type. But the "weird" ordering has saved us 4 bytes
> per structure!
>
> Does C89 allow this, or is it disallowed by something
> in that standard? If so, what?
No version of the Standard describes what alignments
are to be enforced. However, the rules for compatibility
of types guarantee that the same struct type will have the
same arrangement of padding bytes in all translation units.
Could this arrangement be different depending on flags
calling for different "strictnesses" of alignment? Yes, of
course -- but this isn't a contradiction, because using a
different set of compiler flags gives you a different
implementation of C, and the Standard makes no requirement
that translation units compiled by different implementations
must interoperate.
By the way, note that your 8-byte alignment example is
faulty. If a double must be aligned to an 8-byte boundary,
the sizeof a struct containing a double must be a multiple
of 8 bytes. Otherwise, you would not be able to malloc()
an array of two such structs:
struct weird *p = malloc(2 * sizeof *p); // assume 40
0 4 8 16 20 24 28 36 40
|_x__|####|___y____|_z__|_x__|####|___y____|_z__|
^ ^
| |
p p+1
Note that (p+1)->y is mis-aligned.
-- Eric.Sosman@sun.com
- Next message: Robert J. Kolker: "Re: Fundamental Reason for High Achievements of Jews"
- Previous message: Mike Wahler: "Re: [OT, welcome msg, link, redir] linux kernel system call"
- In reply to: Arthur J. O'Dwyer: "Pre-offsetof() question"
- Next in thread: Arthur J. O'Dwyer: "Re: Pre-offsetof() question"
- Reply: Arthur J. O'Dwyer: "Re: Pre-offsetof() question"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|