取消引用类型punned指针将打破严格的混叠规则:将字节数组转换为数字
dereferencing type-punned pointer will break strict-aliasing rules: array of bytes to a number
我已经读过很多关于这个警告的问题(取消引用类型的punned指针将打破严格的混叠规则,取消引用类型punned指示器将打破严格混叠规则[-Wstrict aliasing],什么是严格混叠规则?,"取消引用类型punned指针会打破严格混迭规则"警告和其他),我完全困惑了关于我的警告。
所以我有一个结构:
typedef struct {
unsigned char precision;
unsigned char scale;
unsigned char array[33];
} DBNUMERIC;
从MS SQL Server检索数据时,此结构体由FreeTDS库填充。我知道从array[1]
开始有64位整数(以big-endian表示),我想得到它
int64_t result = 0;
result = be64toh(*((decltype(result)*)(numeric.array + 1)));
但是GCC给了我警告dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
。但如果我使用代码:
int64_t result = 0;
decltype(result)* temp_ptr = (decltype(result)*)(numeric.array + 1);
decltype(result) temp = *temp_ptr;
result = be64toh(temp);
没有关于违反严格别名规则的警告。我不认为这个代码与原来的不同,所以我很困惑。如何将数组中的8个字节转换为int64_t
变量?
这两种情况都违反了严格的别名规则。gcc的严格混叠警告会受到假阴性和假阳性的影响,这取决于警告和优化级别。
如果你想以严格的别名规则不允许的方式键入pun,那么你应该只使用std::memcpy:
std::memcpy(&result, numeric.array+1, sizeof(int64_t ));
我们可以从以下来源看到;这篇文章《类型双关、严格别名和优化》以及我在回答中引用的关于类型双关和并集的std讨论告诉我们,编译器应该足够聪明,可以优化使用memcpy
来生成高效的代码。
相关文章:
- 从不同线程使用int64的不同字节安全吗
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 此代码是否违反一个定义规则
- 在UNIX系统中使用DIR查找文件的字节大小
- 生成文件不对文件使用隐式规则
- 如何使用Crypto++并为RSA返回可打印的字节/字符数组
- std::当在256字节边界上写入整数时,流的奇怪行为
- 变量可能尚未初始化[MIRA 2012规则9.1,强制性]
- 静态结构和一个定义规则
- 当比特(而不是字节)的顺序至关重要时的持久性
- 从文件中读取多个字节,并将它们存储在C++中进行比较
- 如何在文件中查找字节序列
- luaL_dofile在已知良好的字节码上失败,可以使用未编译的版本
- 尽管遵循了规则,内存泄漏在哪里
- 字节到位运算符重载C++
- 在java中读取c++字节的位字段
- 使用 std::vector::reverse_iterator 将 int 序列化为字节向量?
- 字节真的是最小可寻址单元吗
- 取消引用类型punned指针将打破严格的混叠规则:将字节数组转换为数字
- 如何在不违反严格的混叠规则的情况下访问内存映射的多字节寄存器