David Tribble writes:
> VoidHand vHand;
> TypeA *aPtr;
> TypeB *bPtr, bStruct;
> Int16 x;
>
> vHand = DmNewRecord(someOpenDB, dmMaxRecordIndex, sizeof(TypeA) + sizeof(TypeB));
> aPtr = MemHandleLock(vHand);
> bPtr = (TypeB*)(aPtr + 1);
> x = bPtr->n;
>
> The LAST statement is the one I'm curious about - should it work?
In portable, standard C? No. Your cast is invalid on two counts:
1. A pointer to a TypeA might not be adequately aligned for a TypeB. (For
example, if TypeA contained one char and TypeB an int and your compiler
didn't pad structures much, you'd probably have an int at an odd address,
which M68Ks and some other processors don't like much.)
2. You may run into aliasing problems. (For example, consider what value
you'd like x to have after `bPtr->n = 1; aPtr[1]->m = 2; x = bPtr->n'.)
On current Palm OS? Yes, if you're careful. You know what the M68K's
alignment requirements are, and so can make sure that bPtr winds up suitably
aligned, which basically means `even'. And you can either avoid (eg, with
GCC don't use -fstrict-aliasing) or ignore (at your peril) the aliasing
issues. (For lots of discussion of this, go to http://egcs.cygnus.com/ml/gcc/
and search for `-fno-strict-aliasing'.)
> MemMove(&bStruct, aPtr + 1, sizeof(TypeB));
Yes, this is the standard method for avoiding both these issues, but there
is a performance cost, of course.
John