[英]dereferencing type-punned pointer will break strict-aliasing rules: array of bytes to a number
I have already read a number of questions about this warning ( Dereferencing type-punned pointer will break strict-aliasing rules , Dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] , What is the strict aliasing rule? , "dereferencing type-punned pointer will break strict-aliasing rules" warning and others) and got totally confused about my warning. 我已经阅读了有关此警告的许多问题( 取消引用类型化指针将破坏严格别名规则 , 取消引用类型化指针将破坏严格别名规则[-Wstrict-aliasing] , 严格别名化规则是什么? , “取消引用类型化的指针将破坏严格的别名规则”警告和其他警告 ),并对我的警告完全感到困惑。
So I have a struct: 所以我有一个结构:
typedef struct {
unsigned char precision;
unsigned char scale;
unsigned char array[33];
} DBNUMERIC;
This struct is filled by FreeTDS library when retrieving data from MS SQL Server. 从MS SQL Server检索数据时,此结构由FreeTDS库填充。 I know that starting from
array[1]
there is 64-bit integral number (in big-endian) and I want to get it. 我知道从
array[1]
有一个64位整数(在big-endian中),我想得到它。 I use the following code: 我使用以下代码:
int64_t result = 0;
result = be64toh(*((decltype(result)*)(numeric.array + 1)));
But GCC gives me the warning dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
. 但是GCC给我警告,
dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
。 But if I use the code: 但是,如果我使用代码:
int64_t result = 0;
decltype(result)* temp_ptr = (decltype(result)*)(numeric.array + 1);
decltype(result) temp = *temp_ptr;
result = be64toh(temp);
there are no warnings about violating strict-aliasing rules. 没有关于违反严格混叠规则的警告。 I don't think that this code differs from the original, therefore I am confused.
我认为这段代码与原始代码没有什么不同,因此我感到困惑。 How can I convert 8 bytes from the array to a
int64_t
variable? 如何将数组中的8个字节转换为
int64_t
变量?
Both of your cases violate the strict aliasing rules . 您的两种情况都违反了严格的别名规则 。 gcc's strict-aliasing warnings are subject to false negatives and false positives depending on the warning and optimization levels.
gcc的严格混叠警告会受到误报和误报的影响,具体取决于警告和优化级别。
If you want to type-pun in a way not allowed by the strict aliasing rules then you should just use std::memcpy : 如果您想以严格的别名规则所不允许的方式来输入双关语,则应该只使用std :: memcpy :
std::memcpy(&result, numeric.array+1, sizeof(int64_t ));
We can see from the following sources; 我们可以从以下来源看到: this article Type Punning, Strict Aliasing, and Optimization and the std-dicussion conversation on type punning and unions I quote in my answer here tell us that the compiler should be smart enough to optimize for the use of
memcpy
to generate efficient code. 本文的类型调整,严格别名和优化以及关于类型转换和联合的std-dicussion对话在这里在我的回答中告诉我们,编译器应该足够聪明,可以使用
memcpy
进行优化以生成有效的代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.