我正在尝试调用此函数
CHANNEL_ID
但是,我收到了这个错误:
static inline void insert(Buffer *buf, double f, size_t index)
{
insert_64(buf, *(uint64_t *)&f, index);
}
不知道我哪里出错了。
答案 0 :(得分:1)
正如评论中所提到的,尝试将指向一种类型的指针转换为另一种类型的指针会破坏严格的别名规则。您可以使用memcpy
将字节从一种类型复制到另一种类型来解决这个问题:
uint64_t x;
memcpy(&x, &f, sizeof(f));
请注意,x
包含的内容取决于实现,即double
的表示形式是系统大端还是小端,是double
64位,等
答案 1 :(得分:1)
不知道我哪里出错了。
*(uint64_t *)&f
违反了严格别名规则。见Fix for dereferencing type-punned pointer will break strict-aliasing
要解决此问题,请使用memcpy()
,以及@dbush或union
。 union
处理严格别名规则。
void insert2(Buffer *buf, double f, size_t index) {
union {
double d;
uint64_t u64;
} u = { f };
insert_64(buf, u.u64, index);
}
或使用复合文字(自C99起可用)
void insert3(Buffer *buf, double f, size_t index) {
// v-----------------------------------------v compound literal
insert_64(buf, (union { double d; uint64_t u64; }){.d = f}.u64, index);
}
使用C11,我会在下面添加以下内容,以便将来评估正确性。
_Static_assert(sizeof (double) == sizeof (uint64_t), "Unexpected sizes");
注意:稀有平台每个整数和FP类型都有不同的 endian 。