Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to resolve warning: dereferencing type-punned pointer will break strict-aliasing rules

Tags:

c

    #define HTON_I32(x) htonl(x)
inline float  __HTON_F32(float  x)
{
    int i = HTON_I32(*((int *)(&x)));
    return (*((float *)(&i)));
}

How to resolve warning dereferencing type-punned pointer will break strict-aliasing rules in the above code

like image 748
Sudhakar Avatar asked Nov 22 '11 16:11

Sudhakar


2 Answers

Eliminate the type-punning, and replace it with something that isn't fragile in the face of aliasing:

#include <string.h>

inline float __HTON_F32(float x) {
    int i;
    memcpy(&i, &x, sizeof x);
    i = HTON_I32(i);
    memcpy(&x, &i, sizeof x);
    return x;
}

Reasonable optimizing compilers will lower the memcpy calls, and generate equivalent (sometimes better) code to what you get from type-punning.

Another common solution you will see involves unions. All of these solutions assume that sizeof(int) == sizeof(float). You may want to add an assert to that effect.

like image 158
Stephen Canon Avatar answered Sep 28 '22 08:09

Stephen Canon


You can use unions for type-punning, which takes care of possible alignment and aliasing issues (C99:TC3 explicitly mentions that this is indeed legal):

#include <stdint.h>

inline float __HTON_F32(float x) {
    union { float as_float; int32_t as_int; } value = { x };
    value.as_int = HTON_I32(value.as_int);
    return value.as_float;
}
like image 20
Christoph Avatar answered Sep 28 '22 07:09

Christoph