c-我可以通过IEEE双精度往返一个对齐的指针吗



我可以通过双精度往返任何4位对齐的指针吗?我能通过一根绳子往返任何有限的二重吗?

具体来说,在任何使用IEEE浮点的平台上,它符合C11,并且在该平台上静态断言都不失败,下面程序中的断言是否保证通过?

#include <stdint.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <math.h>
int main(void) {
struct {
void *dummy;
} main_struct;
main_struct.dummy = 0;
static_assert(_Alignof(main_struct) >= 4,
"Dummy struct insufficiently aligned");
static_assert(sizeof(double) == sizeof(uint64_t) && sizeof(double) == 8,
"double and uint64_t must have size 8");
double x;
uint64_t ptr = (uint64_t)&main_struct;
assert((ptr & 3) == 0);
ptr >>= 2;
memcpy(&x, &ptr, 8);
assert(!isnan(x));
assert(isfinite(x));
assert(x > 0);
char buf[1000];
snprintf(buf, sizeof buf, "Double is %#.20gn", x);
double q;
sscanf(buf, "Double is %lgn", &q);
assert(q == x);
assert(memcmp(&q, &ptr, 8) == 0);
}

具体来说,在任何使用IEEE浮点、符合C11、静态断言都不失败的平台上,以下程序中的断言是否保证通过?

只有这些要求,那么就没有。排除它的原因如下:

  • 您还没有断言指针的大小是64位或更小
  • 没有任何东西表明指针和双精度在内存中使用相同的endianness。如果指针是big-endian,而doubles是little-endian(或middle endian,或使用其他奇怪的内存格式),那么您的移位不会排除负值、无穷大值或NaN值
  • 指针不能仅仅因为指向对齐的值就保证简单地转换为具有保证为零的低阶位的整数值

在当前的实用平台上,这些反对意见可能有些病态,但在理论上肯定是正确的,并且您的需求列表中没有任何反对意见。

例如,完全可以想象一个具有独立浮点协处理器的体系结构,该协处理器使用与主整数CPU不同的内存格式。事实上,维基百科的文章实际上指出,有一些架构的真实例子可以做到这一点。至于奇怪的指针格式,C FAQ提供了一些有趣的历史示例。

最新更新