[comp.lang.c] Suitably aligned pointers

daveh@marob.MASA.COM (Dave Hammond) (10/14/88)

We use a pretty basic set of memory management routines which
allocate large hunks of memory and parcel it out as requested,
saving malloc the headache of managing huge lists of small buffers.
The problem is the routines don't return a `suitably aligned' pointer,
so the accuracy of casting the return to other than char * is in doubt.

Can someone explain the technique used to suitably align a pointer ?

Dave Hammond
  UUCP: ...!uunet!masa.com!{marob,dsix2}!daveh
DOMAIN: daveh@marob.masa.com
----------------------------------------------------------------------------

g-rh@XAIT.Xerox.COM (Richard Harter) (10/15/88)

In article <345@marob.MASA.COM> daveh@marob.UUCP (Dave Hammond) writes:
>We use a pretty basic set of memory management routines which
>allocate large hunks of memory and parcel it out as requested,
>saving malloc the headache of managing huge lists of small buffers.
>The problem is the routines don't return a `suitably aligned' pointer,
>so the accuracy of casting the return to other than char * is in doubt.

>Can someone explain the technique used to suitably align a pointer ?

"suitably aligned" is a machine dependent notion.  On any given machine
there are address restrictions associated with operations on particular
kinds of primitive objects for the machine.  For example, a move double
word instruction may require that the addresses be even word boundaries.
Malloc returns suitably aligned pointers.  In practice a char pointer
whose offset from a malloc supplied pointer is divible by 8 will also
be suitably aligned.  More generally, replace 8 by the width of a double
in bytes.  This is not guaranteed, but it is pretty safe.  
-- 

In the fields of Hell where the grass grows high
Are the graves of dreams allowed to die.
	Richard Harter, SMDS  Inc.

flaps@dgp.toronto.edu (Alan J Rosenthal) (10/15/88)

In article <345@marob.MASA.COM> daveh@marob.UUCP (Dave Hammond) writes:
>The problem is the routines don't return a `suitably aligned' pointer,
>so the accuracy of casting the return to other than char * is in doubt.
>
>Can someone explain the technique used to suitably align a pointer ?

Well, it can't be done very nicely in a portable way.  It can be done very
easily in a machine-dependent way:  just do this:
	if ((long)p & 1)
	    p++;
for example to enforce even alignment.  Of course, your memory routine will
then have to allocate n + 1 bytes, counting the one you just skipped.  (Don't
assume your machines require even alignment, check it out.)

To make it a little more portable, you have to over-align, so to speak -- there
is no way to figure out the alignment requirement but there is a way to figure
out something which must be a multiple of the alignment requirement.  Take all
types you can think of (whether or not, for example, you must include all of
pointer-to-char, pointer-to-pointer-to-char, and pointer-to-int, can not be
determined, and since there are an infinite number of types this problem is not
solvable in general).  Make a union of them, and then take sizeof it.  If
you're worried that someone might have taken the ansi draft literally and left
out necessary padding of unions, wrap it in a struct first and take sizeof the
struct.

It is not possible to eliminate the assumption that a pointer can fit into some
integral type, although I suppose you could use unsigned long if you think that
would help.  On machines on which a pointer cannot fit into any integral type,
I suppose that a little assembly language is required.

ajr

--
#define __STDC__ 0

jfh@rpp386.Dallas.TX.US (The Beach Bum) (10/16/88)

In article <345@marob.MASA.COM> daveh@marob.UUCP (Dave Hammond) writes:
>We use a pretty basic set of memory management routines which
>allocate large hunks of memory and parcel it out as requested,
>saving malloc the headache of managing huge lists of small buffers.
>The problem is the routines don't return a `suitably aligned' pointer,
>so the accuracy of casting the return to other than char * is in doubt.
>
>Can someone explain the technique used to suitably align a pointer ?

You can't do it in a portable fashion.  Different hardware has different
requirements for producing a ``suitably aligned'' pointer.

Your best bet is to determine the alignment requirements for the largest
hardware supported object, i.e., double precision float.  Then, find a
way to create a pointer properly aligned for that object.

The following is only food for thought.  Don't believe a word of it ...

One good approach would be to hand out memory in units of some
type T, where T is this largest supported object.  Memory is now a
[ presumably ] linear array of objects of size sizeof(T), and since T
requires maximal alignment [ so the theory goes ], allocating a new
memory region in the array will automatically produce an address which
is maximally aligned.  This pointer then needs to be coerced into some
form which can be cast into any other pointer type.  [ which as everyone
will tell you is generally a no-op anyhow ]

Hope this helps somewhat.
-- 
John F. Haugh II                        +----Make believe quote of the week----
VoiceNet: (214) 250-3311   Data: -6272  | Nancy Reagan on Richard Stallman:
InterNet: jfh@rpp386.Dallas.TX.US       |          "Just say `Gno'"
UucpNet : <backbone>!killer!rpp386!jfh  +--------------------------------------

dik@cwi.nl (Dik T. Winter) (10/22/88)

In article <8810151524.AA16480@explorer.dgp.toronto.edu> flaps@dgp.toronto.edu (Alan J Rosenthal) writes:
 > 
 > In article <345@marob.MASA.COM> daveh@marob.UUCP (Dave Hammond) writes:
 > >Can someone explain the technique used to suitably align a pointer ?
 > 
 > Well, it can't be done very nicely in a portable way.  It can be done very
 > easily in a machine-dependent way:  just do this:
 > 	if ((long)p & 1)
 > 	    p++;
 > for example to enforce even alignment.
It is carefully mentioned that this is machine dependent, but not for what
machines.  This will fail on some.  On at least one machine, to get even
byte alignment, it suffices to do:
	p = (char *)(int *)p;
(Yes, it uses different formats for char* and int*.)
-- 
dik t. winter, cwi, amsterdam, nederland
INTERNET   : dik@cwi.nl
BITNET/EARN: dik@mcvax