A
av
Now, you can avoid the casts by "cheating" with a "void *"
temporary variable:
T *p;
void *tmp;
T2 *q;
p = malloc(sizeof *p + N); /* room for 1 p, plus N extra bytes */
if (p == NULL) ... handle error ...
*p = whatever; /* OK */
tmp = p + 1; /* OK */
q = tmp; /* danger */
Even though the cast has now been removed, the danger remains.
The problem is -- still -- that "p + 1" is well-aligned for use as
a "T" (because p came from malloc, so it was well-aligned to start
with), but not necessarily for use as a "T2".
Again, the underlying fundamental problem -- which is hardware
and sometimes compiler dependent -- is "alignment".
It would perhaps be nice if C had a tool for checking whether
something was "well-aligned":
tmp = p + 1;
if (IS_WELL_ALIGNED_FOR_USE_AS_A_T2(tmp))
... proceed ...
else
... something ...
except this leaves two problems, one obvious:
- what do we put in the "else"?
and one slightly less obvious:
- what would we need to do to *guarantee* that tmp is well-aligned
for use as a T2?
i try the answer
#define IS_WELL_ALIGNED_FOR_USE_AS_A_T2(tmp) !((tmp)& (sizeof(T2)-1))
should be ok for all the above cases (x86, powerpc, arm)