Topic: Object alignment requirements


Author: maxtal@Physics.usyd.edu.au (John Max Skaller)
Date: 1995/06/13
Raw View
>Ed Osinski (osinski@valis.cs.nyu.edu) wrote:
>: The draft standard seems to have little to say about what the alignment
>: requirements for objects of various types are.  Almost everything seems
>: to be implementation dependent.  There doesn't even seem to be any
>: requirement for "larger" integral types to have alignment requirements at
>: least as strong as "smaller" types.  For example, it seems permissible
>: for int to have stricter alignment requirements than long.  Am I
>: misreading the draft, or did I miss the appropriate section(s)?

 I could find nothing, but the intent is to stick with the
semantics intended by ISO C.

>:     union {
>:        char[sizeof(Atom)] atomData;
>:        char[sizeof(InternalNode)] internalData;
>:     };
>
>: and use placement new and casting to manipulate the correct variant.
>
>: Unfortunately, this doesn't guarantee that the union will be aligned
>: properly.

 Hey -- that isn't a union. It is an anonymous union
which is a completely different kind of entity.

 The following should always work:

 struct align {char a; };
   union dummy {
       align a;
        char[sizeof(Atom)] atomData;
        char[sizeof(InternalNode)] internalData;
    };

because the C rules require the members of a union to
"start at the same address". Since the union contains
a struct which is assured of having the tightest alignment
constraints, atomData and internalData will always be
aligned correctly.

[I'm a not claiming you can deduce this from the C++ CD,
but I believe you can deduce it from the ISO C Standard]

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189





Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1995/06/13
Raw View
In article 5id@metro.ucc.su.OZ.AU, maxtal@Physics.usyd.edu.au (John Max Skaller) writes:

> The following should always work:
>
> struct align {char a; };
>   union dummy {
>       align a;
>        char[sizeof(Atom)] atomData;
>        char[sizeof(InternalNode)] internalData;
>    };

>because the C rules require the members of a union to
>"start at the same address". Since the union contains
>a struct which is assured of having the tightest alignment
>constraints, atomData and internalData will always be
>aligned correctly.

Perhaps you could point out where a struct containing only a char
must have the "tightest alignment constraints". It seems to me a
double, for example, might require alignment on, say, an 8-byte
boundary, where 'align' required alignment on a 4-byte boundary.
This is the case on Sparc, for example, and I don't think any
provision of the C or C++ standard is violated.

---
Steve Clamage, stephen.clamage@eng.sun.com







Author: osinski@valis.cs.nyu.edu (Ed Osinski)
Date: 1995/06/13
Raw View
In article <3rkvek$5id@metro.ucc.su.OZ.AU>, maxtal@Physics.usyd.edu.au (John Max Skaller) writes:
|> >Ed Osinski (osinski@valis.cs.nyu.edu) wrote:
|> >: The draft standard seems to have little to say about what the alignment
|> >: requirements for objects of various types are.  Almost everything seems
|> >: to be implementation dependent.  There doesn't even seem to be any
|> >: requirement for "larger" integral types to have alignment requirements at
|> >: least as strong as "smaller" types.  For example, it seems permissible
|> >: for int to have stricter alignment requirements than long.  Am I
|> >: misreading the draft, or did I miss the appropriate section(s)?
|>
|>  I could find nothing, but the intent is to stick with the
|> semantics intended by ISO C.

Ah, that's good -- I thought maybe it was overlooked.  Unfortunately,
I don't have a copy -- does it have at least the requirements I
complained about C++ not having above?

|> >:     union {
|> >:        char[sizeof(Atom)] atomData;
|> >:        char[sizeof(InternalNode)] internalData;
|> >:     };
|> >
|> >: and use placement new and casting to manipulate the correct variant.
|> >
|> >: Unfortunately, this doesn't guarantee that the union will be aligned
|> >: properly.
|>
|>  Hey -- that isn't a union. It is an anonymous union
|> which is a completely different kind of entity.

But does it behave differently from a named union wrt alignment?  I
didn't see anything in the short section on unions(9.6) in the draft
that would indicate so.

|>  The following should always work:
|>
|>  struct align {char a; };
|>    union dummy {
|>        align a;
|>         char[sizeof(Atom)] atomData;
|>         char[sizeof(InternalNode)] internalData;
|>     };
|>
|> because the C rules require the members of a union to
|> "start at the same address". Since the union contains
|> a struct which is assured of having the tightest alignment
   ^^^^^^^^       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|> constraints, atomData and internalData will always be
   ^^^^^^^^^^^

That's very good news.  I'll be 'fixing' my code real soon now :-)

--
---------------------------------------------------------------------
 Ed Osinski
 Computer Science Department, New York University
 E-mail:  osinski@cs.nyu.edu
---------------------------------------------------------------------
"No, no, no, don't tug on that. You never know what it might be attached to."
 -- Buckaroo Bonzai to assistant during brain surgery





Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1995/06/14
Raw View
In article <3rl6r5$12k@cmcl2.NYU.EDU> osinski@valis.cs.nyu.edu (Ed
Osinski) writes:

|> In article <3rkvek$5id@metro.ucc.su.OZ.AU>, maxtal@Physics.usyd.edu.au (John Max Skaller) writes:
|> |> >Ed Osinski (osinski@valis.cs.nyu.edu) wrote:

|> |> >:     union {
|> |> >:        char[sizeof(Atom)] atomData;
|> |> >:        char[sizeof(InternalNode)] internalData;
|> |> >:     };
|> |> >
|> |> >: and use placement new and casting to manipulate the correct variant.
|> |> >
|> |> >: Unfortunately, this doesn't guarantee that the union will be aligned
|> |> >: properly.
|> |>
|> |>  Hey -- that isn't a union. It is an anonymous union
|> |> which is a completely different kind of entity.

|> But does it behave differently from a named union wrt alignment?  I
|> didn't see anything in the short section on unions(9.6) in the draft
|> that would indicate so.

Frankly, except that it doesn't have a name, I don't really see any
difference between an anonymous union and another union.

OK...  If the anonymous union is a member of a larger structured data
type, its names are injected into this data type.  Thus, you can
write:

 struct A { union { a1 , a2 } } ;
 A               anA ;
 anA.a1 ;   //  Valid expression

But I don't see where this affects what a union is in any significant
way.

|> |>  The following should always work:
|> |>
|> |>  struct align {char a; };
|> |>    union dummy {
|> |>        align a;
|> |>         char[sizeof(Atom)] atomData;
|> |>         char[sizeof(InternalNode)] internalData;
|> |>     };
|> |>
|> |> because the C rules require the members of a union to
|> |> "start at the same address". Since the union contains
|> |> a struct which is assured of having the tightest alignment
|>    ^^^^^^^^       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|> |> constraints, atomData and internalData will always be
|>    ^^^^^^^^^^^

|> That's very good news.  I'll be 'fixing' my code real soon now :-)

It is regretfully very wrong news, at least with regards to the C
standard (and most of the implementations I'm familiar with).  I think
that John is confusing the C requirement that all pointers to struct
have the same *representation* with alignment requirements.  (I don't
think that the C standard actually says explicitly that all pointers
to struct must have the same representation, but some of the wizards
in comp.std.c have managed to show that any implementation using
different representations for different structs must violate other
constraints.)

I've traditionally used the following:

 union align { long l ; double d ; void* p , void (*pf)() } ;

to force alignment.  I suspect that there is a machine out there
somewhere for which this is not sufficient, but it would have to have
a pretty wierd architecture.  (If you know of this machine, I'd been
interesting in hearing about it.  And in knowing what I should add to
my union to make it fail-safe.)
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                              -- Beratung in industrieller Datenverarbeitung







Author: osinski@valis.cs.nyu.edu (Ed Osinski)
Date: 1995/06/14
Raw View
In article <KANZE.95Jun14112105@slsvhdt.lts.sel.alcatel.de>, kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763) writes:
|> In article <3rl6r5$12k@cmcl2.NYU.EDU> osinski@valis.cs.nyu.edu (Ed
|> Osinski) writes:
|>
|> |> In article <3rkvek$5id@metro.ucc.su.OZ.AU>, maxtal@Physics.usyd.edu.au (John Max Skaller) writes:

 - some discussion of unions vs. anonymous unions skipped -

|> |> |>  The following should always work:
|> |> |>
|> |> |>  struct align {char a; };
|> |> |>    union dummy {
|> |> |>        align a;
|> |> |>         char[sizeof(Atom)] atomData;
|> |> |>         char[sizeof(InternalNode)] internalData;
|> |> |>     };
|> |> |>
|> |> |> because the C rules require the members of a union to
|> |> |> "start at the same address". Since the union contains
|> |> |> a struct which is assured of having the tightest alignment
|> |>    ^^^^^^^^       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|> |> |> constraints, atomData and internalData will always be
|> |>    ^^^^^^^^^^^
|>
|> |> That's very good news.  I'll be 'fixing' my code real soon now :-)
|>
|> It is regretfully very wrong news, at least with regards to the C
|> standard (and most of the implementations I'm familiar with).  I think
|> that John is confusing the C requirement that all pointers to struct
|> have the same *representation* with alignment requirements.  (I don't
|> think that the C standard actually says explicitly that all pointers
|> to struct must have the same representation, but some of the wizards
|> in comp.std.c have managed to show that any implementation using
|> different representations for different structs must violate other
|> constraints.)
|>
|> I've traditionally used the following:
|>
|>  union align { long l ; double d ; void* p , void (*pf)() } ;
|>
|> to force alignment.  I suspect that there is a machine out there
|> somewhere for which this is not sufficient, but it would have to have
|> a pretty wierd architecture.  (If you know of this machine, I'd been
|> interesting in hearing about it.  And in knowing what I should add to
|> my union to make it fail-safe.)

Arrrgh!  That brings me back to what I've been using so far.  I guess
it's good enough, but it's annoying that the standard isn't a bit more
specific about this issue.  In my original post I pointed out that,
aside from the fact that this is not absolutely guaranteed to work, a
union with this extra stuff in it may take up more room than a union
with just the *useful* components!

Hmmm, here's an idea -- does the standard say anything about alignment
requirements of arrays of 0 size?

... looking in the draft ... finding section 8.3.4 which discusses
arrays ... look of puzzlement ...

It says that arrays of 0 length cannot be declared.  They seem rather
innocuous, and sound like just the thing to solve the problem
mentioned in the previous paragraph.  That is, if arrays with 0
elements were allowed, it would be useful if their alignment
requirements were the same as those for arrays with >0 elements.  Is
there a reason for banning them?

--
---------------------------------------------------------------------
 Ed Osinski
 Computer Science Department, New York University
 E-mail:  osinski@cs.nyu.edu
---------------------------------------------------------------------
"No, no, no, don't tug on that. You never know what it might be attached to."
 -- Buckaroo Bonzai to assistant during brain surgery





Author: ray@ray_sparc.orem.novell.com (Ray Whitmer)
Date: 1995/06/01
Raw View
Ed Osinski (osinski@valis.cs.nyu.edu) wrote:
: The draft standard seems to have little to say about what the alignment
: requirements for objects of various types are.  Almost everything seems
: to be implementation dependent.  There doesn't even seem to be any
: requirement for "larger" integral types to have alignment requirements at
: least as strong as "smaller" types.  For example, it seems permissible
: for int to have stricter alignment requirements than long.  Am I
: misreading the draft, or did I miss the appropriate section(s)?

: Lest this seem merely academic, let me pose the following question.  I
: want to define a class Tree which has as a data member either an Atom or
: an InternalNode.  One obvious, but incorrect, approach would be to have a
: tag and a union:

:  class Tree {
:     ...
:     enum Tag { IsAtom, IsInternal };

:     Tag tag;
:     union {
:        Atom atom;
:        InternalNode internal;
:     };
:     ...
:  };

: If Atom or InternalNode are non-trivial classes, however, they cannot be
: data members of unions.  Wishing to avoid allocating them on the heap, I
: can change the union to:

:     union {
:        char[sizeof(Atom)] atomData;
:        char[sizeof(InternalNode)] internalData;
:     };

: and use placement new and casting to manipulate the correct variant.

: Unfortunately, this doesn't guarantee that the union will be aligned
: properly.  A typical trick is to put in a few dummy members for the sole
: purpose of getting proper alignment, so that the union looks like:

:     union {
:        long dummy1;
:        double dummy2;
:        void *dummy3;
:        int (*dummy4)();

:        char[sizeof(Atom)] atomData;
:        char[sizeof(InternalNode)] internalData;
:     };

: The problem is that this doesn't seem to guarantee correct alignment
: either.  In order to do so, it seems to be necessary to declare dummy
: union members of all predefined types!  This has, among others, the
: unfortunate disadvantage that the size of the union may now be larger
: than the maximum of the sizes of Atom and InternalData.

: To summarize:

: * Is there any portable way to assure correct alignment for an object of
:   arbitrary type?
: * Is there a way to determine at compile time (preferably something like
:   sizeof) what the alignment requirements of a particular type are?
:   Something that could be used like so:

:  union {
:     align(T);  // force correct alignment for an object of type T
:     ...
:  };
: --
: ---------------------------------------------------------------------
:  Ed Osinski
:  Computer Science Department, New York University
:  E-mail:  osinski@cs.nyu.edu
: ---------------------------------------------------------------------
: "No, no, no, don't tug on that. You never know what it might be attached
: to."
:  -- Buckaroo Bonzai to assistant during brain surgery

I have tried to solve a similar problem as follows:

struct T_align_test {
 char misalign[1];
 T align;
};

enum {T_alignment = sizeof(T_align_test) - sizeof(T)};

As long as all alignment is power of two and the compiler behaves reasonably,
this gives me a value 1, 2, 4, 8, 16, 32, etc. which tells me how the compiler
is aligning the structure so I can manually manipulate the alignment.  Exactly
how perfectly portable I do not know.  I assume that there will be no further
padding of the structure T_align_test because T has already been padded and
represents the greatest alignment requirement of the structure.

So then if X precedes T or Q I can calculate:

enum {align = T_alignment > Q_alignment ? T_alignment : Q_alignment};

and use:

char fill[((sizeof(X) + align - 1) & (-align)) - sizeof(X)];

so that my next character array is properly aligned to actually hold either T
or Q.

I have not read the wp to know exactly how many invalid assumptions I have made
here, but in real life it seems to work pretty well.

I hope this is useful, if for nothing else, to pick apart.

Ray Whitmer
ray@orem.novell.com






Author: osinski@valis.cs.nyu.edu (Ed Osinski)
Date: 1995/05/31
Raw View
The draft standard seems to have little to say about what the alignment
requirements for objects of various types are.  Almost everything seems
to be implementation dependent.  There doesn't even seem to be any
requirement for "larger" integral types to have alignment requirements at
least as strong as "smaller" types.  For example, it seems permissible
for int to have stricter alignment requirements than long.  Am I
misreading the draft, or did I miss the appropriate section(s)?

Lest this seem merely academic, let me pose the following question.  I
want to define a class Tree which has as a data member either an Atom or
an InternalNode.  One obvious, but incorrect, approach would be to have a
tag and a union:

 class Tree {
    ...
    enum Tag { IsAtom, IsInternal };

    Tag tag;
    union {
       Atom atom;
       InternalNode internal;
    };
    ...
 };

If Atom or InternalNode are non-trivial classes, however, they cannot be
data members of unions.  Wishing to avoid allocating them on the heap, I
can change the union to:

    union {
       char[sizeof(Atom)] atomData;
       char[sizeof(InternalNode)] internalData;
    };

and use placement new and casting to manipulate the correct variant.

Unfortunately, this doesn't guarantee that the union will be aligned
properly.  A typical trick is to put in a few dummy members for the sole
purpose of getting proper alignment, so that the union looks like:

    union {
       long dummy1;
       double dummy2;
       void *dummy3;
       int (*dummy4)();

       char[sizeof(Atom)] atomData;
       char[sizeof(InternalNode)] internalData;
    };

The problem is that this doesn't seem to guarantee correct alignment
either.  In order to do so, it seems to be necessary to declare dummy
union members of all predefined types!  This has, among others, the
unfortunate disadvantage that the size of the union may now be larger
than the maximum of the sizes of Atom and InternalData.

To summarize:

* Is there any portable way to assure correct alignment for an object of
  arbitrary type?
* Is there a way to determine at compile time (preferably something like
  sizeof) what the alignment requirements of a particular type are?
  Something that could be used like so:

 union {
    align(T);  // force correct alignment for an object of type T
    ...
 };
--
---------------------------------------------------------------------
 Ed Osinski
 Computer Science Department, New York University
 E-mail:  osinski@cs.nyu.edu
---------------------------------------------------------------------
"No, no, no, don't tug on that. You never know what it might be attached
to."
 -- Buckaroo Bonzai to assistant during brain surgery