C 在阳光下';s libm,*(1+;(int*)和x)做什么(其中x是double类型)?
表情C 在阳光下';s libm,*(1+;(int*)和x)做什么(其中x是double类型)?,c,floating-point,C,Floating Point,表情 #define __HI(x) *(1+(int*)&x) 在中定义,在中定义。它用于Sun数学库的大多数程序,例如 double y[2],z=0.0; int n,ix; /*x的高位词*/ ix=高(x); /*|x | ~
#define __HI(x) *(1+(int*)&x)
在中定义,在中定义。它用于Sun数学库的大多数程序,例如
double y[2],z=0.0;
int n,ix;
/*x的高位词*/
ix=高(x);
/*|x | ~
意思是:取x的地址(&x
),将其转换为指向int(int*)
,添加1,然后取消对结果指针的引用。假设Sun正在使用,这意味着内存中的值如下所示:
<sign (1 bit)><exponent (11 bits)><significand (52 bits)>
如果sizeof(int)
为32位,这将找到双精度
在内存中的位置,然后递增指向下一个int
的指针,该指针包含符号、指数和数字的前21位。它会产生未定义的行为。@Olaf不止这些。它违反了严格的别名规则,因此编译器不需要保留o对\uuuHi(x)
和x
的读/写顺序。这不仅仅是与实现交互所需的实现定义的行为。还要注意,宏未得到充分保护。\uHi(x+3)
和\uHi(x)[y]
不会做读者认为他们会做的事情。实际的代码在许多操作系统中都是继承的,包括大多数基于BSD的发行版,通过一些策略性的谷歌搜索,你应该能够观察到,在那些更注重标准的地方,宏\uhi
被更符合标准的东西所取代:@Olaf胡说八道。编译器会“错误编译”忽略严格的别名规则的代码,不管代码作者认为代码应该在目标平台、低级代码或其他平台上执行什么。代码作者会一直花在调查“错误编译错误”上将被浪费,因为编译器的作者只会告诉他们这是他们应得的。代码的作者将被留下来写一篇糟糕的博客文章,并称编译器的作者不称职。这在过去已经发生过多次,可根据请求提供参考。它被称为\uu HI
,这是一个保留的名称根据标准。您已经通过定义名为\uu HI
的内容获得了UB,无论其内容如何。非常好的解释!谢谢。
*(1+(int*)&x)
<sign (1 bit)><exponent (11 bits)><significand (52 bits)>