Aliasing in C99
- From: David Brown <david.brown@xxxxxxxxxxxx>
- Date: Thu, 31 May 2012 09:01:02 -0500
I am trying to figure out how to get aliasing to work correctly according
to the C99 rules. For example, converting between a float and its binary
representation.
float negPCast(float x) {
uint32_t u = *((uint32_t *) &x);
u ^= 0x80000000u;
return *((float *) &u);
}
In the absence of type-based aliasing, this will negate a float using
just a simple xor operation (ignore any issues with endianness, int
sizes, NaNs, etc., since this is just an example).
The pointer typecasting here will break strict aliasing rules, and is
therefore not valid C99. (I'm guessing that in this case, most compilers
will generate code that works as desired - but I'm looking for strictly
conforming methods.)
It is possible to re-implement it using type-punning unions:
float negUnion(float x) {
union { float f; uint32_t u; } uf;
uf.f = x;
uf.u ^= 0x80000000;
return uf.f;
}
This doesn't use pointer typecasting, but I believe type-punning unions
are undefined in C but implemented "properly" in most compilers.
It is also possible to use pointers to unions in casts:
float negUnionPCast(float x) {
typedef union { float f; uint32_t u; } UF;
uint32_t u = ((UF*) &x)->u;
u ^= 0x80000000u;
return ((UF*) &u)->f;
}
I /think/ pointer casts like this are not subject to strict aliasing
rules, but I don't know if the union usage is valid.
Does anyone know of other ways that are strictly valid and defined in
C99, and that also are efficient in use (I'd like to avoid things like
casting back and forth between char or char pointers, or volatile
accesses, etc.)?
.
- Follow-Ups:
- Re: Aliasing in C99
- From: Tim Rentsch
- Re: Aliasing in C99
- From: Xavier Roche
- Re: Aliasing in C99
- From: Eric Sosman
- Re: Aliasing in C99
- From: James Kuyper
- Re: Aliasing in C99
- Prev by Date: Re: Reasonably priced C11 now available
- Next by Date: Re: Aliasing in C99
- Previous by thread: Re: Reasonably priced C11 now available
- Next by thread: Re: Aliasing in C99
- Index(es):
Relevant Pages
|