#define HTON_I32(x) htonl(x)
inline float __HTON_F32(float x)
{
int i = HTON_I32(*((int *)(&x)));
return (*((float *)(&i)));
}
如何解决上面的代码如何解决警告:提领类型-punned指针将打破严格走样规则
#define HTON_I32(x) htonl(x)
inline float __HTON_F32(float x)
{
int i = HTON_I32(*((int *)(&x)));
return (*((float *)(&i)));
}
如何解决上面的代码如何解决警告:提领类型-punned指针将打破严格走样规则
消除类型双关警告dereferencing type-punned pointer will break strict-aliasing rules
,并与一些与工作不”更换T IN混叠面对脆弱:
#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;
}
合理的优化编译器会降低memcpy
调用,生成当量(有时更好)代码,您从类型双关会得到什么。
您将看到的另一个常见解决方案涉及工会。所有这些解决方案都假设为sizeof(int) == sizeof(float)
。你可能想要添加一个assert来达到这个效果。
您可以使用类型双关,这需要照顾的可能对齐和走样的问题工会(C99:TC3明确提到,这确实是合法的):
#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;
}
你可以用编译-fno严格 - 启用标志。这将删除有关严格别名问题的警告 –
@TonyTheLion:它不能解决问题,它隐藏了它,并隐藏了代码中的其他潜在问题。不是一个好主意。 – Mat
@Mat,不,这会以优化成本解决问题。 –