Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/facebook/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
-Werror=C中的严格别名错误_C - Fatal编程技术网

-Werror=C中的严格别名错误

-Werror=C中的严格别名错误,c,C,我正在尝试调用此函数 static inline void insert(Buffer *buf, double f, size_t index) { insert_64(buf, *(uint64_t *)&f, index); } 但是,我得到了这个错误: error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing] 不知道哪里出错。正如

我正在尝试调用此函数

static inline void insert(Buffer *buf, double f, size_t index)
{
   insert_64(buf, *(uint64_t *)&f, index);
}
但是,我得到了这个错误:

error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing]

不知道哪里出错。

正如评论中提到的,尝试将指向一种类型的指针转换为另一种类型的指针会违反严格的别名规则。您可以通过使用
memcpy
将字节从一种类型复制到另一种类型来解决此问题:

uint64_t x;
memcpy(&x, &f, sizeof(f));
请注意,
x
包含的内容取决于实现,即
double
的表示形式是什么,是系统大端还是小端,是
double
64位,等等

不知道我错在哪里

*(uint64\u t*)&f
打破了严格的别名规则。看

要修复此问题,请使用
memcpy()
以及由或
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开始提供)


对于C11,我将添加以下内容,以便将来对正确性进行评估

_Static_assert(sizeof (double) == sizeof (uint64_t), "Unexpected sizes");


注意:很少有平台具有不同的endian/integer和FP类型。

*(uint64\u t*)和f
。你不能假装指向一个
float
的指针是指向一个
uint64\u t
的指针,然后侥幸逃脱。可能重复@leedinelcrocker取消引用新指针是UB,OP肯定是做错了什么。看看这里:不,这不仅仅是关于可移植性。打破严格的别名规则并进行一些优化可能会导致更有趣的事情。请看这里:
_Static_assert(sizeof (double) == sizeof (uint64_t), "Unexpected sizes");