Aliasing in C99



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.)?

.



Relevant Pages

  • Re: weird code.
    ... never seen this kind of declaration ever. ... The variable data is a float pointer? ... array of 16384 float objects. ...
    (comp.lang.c)
  • Re: Help a beginner - function with pointer ...
    ... i thought (float *) T would be appealing to ... The result is the value obtained by converting the ... `T' refers to a one-dimensional array whose elements are also ... using a pointer to the array's first element. ...
    (comp.lang.c)
  • Re: new foo[42]
    ... > First question: ... 42 type 'float' objects, and returns the address ... value in the pointer object 'foo'. ... The first form above dynamically allocates an array (which ...
    (comp.lang.cpp)
  • Re: Aliasing in C99
    ... For example, converting between a float ... and its binary representation. ... This doesn't use pointer typecasting, ... If you had an actual union object, conversions of pointers to it into ...
    (comp.lang.c)
  • Re: is it safe to zero float array with memset?
    ... >> Not if you then try to use the value as a float or as a pointer. ... >> load it into an address register (no dereference needed). ... If it's a matter of the implementation itself, *IT'S NOT SAFE*. ...
    (comp.lang.c)