2011-11-22 46 views
5
#define HTON_I32(x) htonl(x) 
inline float __HTON_F32(float x) 
{ 
    int i = HTON_I32(*((int *)(&x))); 
    return (*((float *)(&i))); 
} 

如何解决上面的代码如何解决警告:提领类型-punned指针将打破严格走样规则

+0

你可以用编译-fno严格 - 启用标志。这将删除有关严格别名问题的警告 –

+0

@TonyTheLion:它不能解决问题,它隐藏了它,并隐藏了代码中的其他潜在问题。不是一个好主意。 – Mat

+0

@Mat,不,这会以优化成本解决问题。 –

回答

9

消除类型双关警告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来达到这个效果。

1

您可以使用类型双关,这需要照顾的可能对齐和走样的问题工会(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; 
} 
+1

对于任何想要TC3引用的用户,请参阅第6.5.2.3节脚注82 –

+0

。 ...和C1x四月草案同一部分的脚注95;) – Christoph

+0

这究竟是做什么的。 ? value.as_int = HTON_I32(value.as_int); – Sudhakar

相关问题