C 假设sizeof(double)>;=sizeof(void*)?

C 假设sizeof(double)>;=sizeof(void*)?,c,portability,sizeof,c99,void-pointers,C,Portability,Sizeof,C99,Void Pointers,假设sizeof(double)始终大于或等于sizeof(void*),安全吗 在某种意义上说,以下是可移植的吗 int x = 100; double tmp; union { double dbl; void* ptr; } conv; conv.ptr = (void*)&x; tmp = conv.dbl; conv.dbl = tmp; printf("%d\n", *((int*)conv.ptr)); 在我测试过的少数几台机器上,但是如果sizeof(vo

假设
sizeof(double)
始终大于或等于
sizeof(void*)
,安全吗

在某种意义上说,以下是可移植的吗

int x = 100;
double tmp;

union {
  double dbl;
  void* ptr;
} conv;

conv.ptr = (void*)&x;
tmp = conv.dbl;

conv.dbl = tmp;
printf("%d\n", *((int*)conv.ptr));

在我测试过的少数几台机器上,但是如果
sizeof(void*)>sizeof(double)

大小与它无关,我可以看到这是一个可怕的错误。始终会有一些位存储在其中,并且大小始终足以容纳
void*
。出错的地方是,您将几乎随机的位模式解释为指针,这除了崩溃之外没什么作用,但很可能您已经知道了这一点。不要这样做。

尺寸与此无关。始终会有一些位存储在其中,并且大小始终足以容纳
void*
。出错的地方是,您将几乎随机的位模式解释为指针,这除了崩溃之外没什么作用,但很可能您已经知道了这一点。不要这样做。

在当前系统上是的
double
在所有当前和未来的系统上都是64位的,因为它们与IEEE算法的双精度一致。未来指针不太可能变大,但肯定有可能变大——可能不是为了更大的地址空间,而是为了携带边界信息


在任何情况下,在当前系统上依赖
double
void*
之间的任何关系似乎都是一个非常糟糕的主意是的
double
在所有当前和未来的系统上都是64位的,因为它们与IEEE算法的双精度一致。未来指针不太可能变大,但肯定有可能变大——可能不是为了更大的地址空间,而是为了携带边界信息


在任何情况下,依赖
double
void*
之间的任何关系似乎都是一个非常糟糕的主意。…

不,这样假设是不安全的。例如,为什么
void*
不能为16字节?“这是我所怀疑的,但我似乎找不到明确说明这一点的相关参考资料。我正在寻找可以用来打败上述代码作者的东西。我认为AS-400虚拟指令集有128位指针。@ThomasPadron McCarthy——是的。IBM iSeries--16字节指针。在AS/400/iSeries上,上述操作将导致指针“未标记”且无效。不,假设这样做是不安全的。例如,为什么
void*
不能为16字节?“这是我所怀疑的,但我似乎找不到明确说明这一点的相关参考资料。我正在寻找可以用来打败上述代码作者的东西。我认为AS-400虚拟指令集有128位指针。@ThomasPadron McCarthy——是的。IBM iSeries--16字节指针。在AS/400/iSeries上,上述操作将导致指针变为“未标记”且无效。他所使用的
double
for就是移动位。实际数据从
int*
开始,最终解释为
int*
。但他担心通过
double
传递会丢失指针的一些位。如果
sizeof(double)>=sizeof(void*)
,则不应发生丢失。请注意,简单地加载/存储double可能会改变其位模式。@HotLicks:如果我们讨论的是IEEE算法,我认为不会发生这种情况。所有的
double
表示都是有效的(可以是正常数或非正常数、无穷大或NaN)。每个非NAN都有一个唯一的表示形式(因此加载和存储它不能改变表示形式,或者它也会改变值),并且NAN被有意地保留(如果可能,甚至在算术和超越函数中)我认为有一种情况——非规范化的零,可能是——允许通过加载/存储更改位模式。如果对该值执行了实际“操作”的提示,也可以进行一些更改;唯一的“多个零表示”是正零和负零,它们不会因加载/存储而改变;它们是不同的值,但可以通过一些“琐碎”的操作(如加零)进行更改。请注意,甚至有些操作您可以安全地对double执行双射操作,例如一元减号。他所使用的
double
for就是移动位。实际数据从
int*
开始,最终解释为
int*
。但他担心通过
double
传递会丢失指针的一些位。如果
sizeof(double)>=sizeof(void*)
,则不应发生丢失。请注意,简单地加载/存储double可能会改变其位模式。@HotLicks:如果我们讨论的是IEEE算法,我认为不会发生这种情况。所有的
double
表示都是有效的(可以是正常数或非正常数、无穷大或NaN)。每个非NAN都有一个唯一的表示形式(因此加载和存储它不能改变表示形式,或者它也会改变值),并且NAN被有意地保留(如果可能,甚至在算术和超越函数中)我认为有一种情况——非规范化的零,可能是——允许通过加载/存储更改位模式。如果对该值执行了实际“操作”的提示,也可以进行一些更改;唯一的“多个零表示”是正零和负零,它们不会因加载/存储而改变;它们是不同的值,但可以通过一些“琐碎”的操作(如加零)进行更改。请注意,甚至有些操作您可以saf