[Image-SIG] rehash_collide, strict aliasing, and pointer sizes
Brian Crowell
brian at fluggo.com
Sun Oct 14 05:56:05 CEST 2012
I'm trying to iron out some of the strict-aliasing warnings that come
up when building the code under Python 3. (Strict aliasing is a C rule
against using the same pointer as two different types, which, when
followed, gives the optimizer a huge advantage. This didn't come up
under Python 2, because Python 2 code couldn't be built with strict
aliasing on, so it becomes an issue in Python 3 code where strict
aliasing is on by default.)
I came across this strange function in Quant.c:
static void
rehash_collide(HashTable h,
void **keyp,
void **valp,
void *newkey,
void *newval)
{
*valp=(void *)((*(int *)valp)+(*(int *)&newval));
}
This function sets off red flags in my brain. It's essentially casting
two void pointers to ints to add them and then cast them back.
Now, the strict-aliasing-safe version is not hard to write:
static void
rehash_collide(HashTable h,
void **keyp,
void **valp,
void *newkey,
void *newval)
{
union {
void *ptr;
int val;
} uresult, uvalp = { *valp }, unewval = { newval };
uresult.val = uvalp.val + unewval.val;
*valp = uresult.ptr;
}
...but the fact that it equates the sizes of ints and void pointers
worries me. Is there a good reason this function isn't written:
static void
rehash_collide(HashTable h,
void **keyp,
void **valp,
void *newkey,
void *newval)
{
*valp=(void *)(((size_t) *valp) + ((size_t) newval));
}
...?
--Brian
More information about the Image-SIG
mailing list