取消引用类型双关指针将破坏严格别名规则:字节数组到数字

use*_*575 3 c++ gcc strict-aliasing gcc-warning

我已经阅读了许多有关此警告的问题(取消引用类型双关指针会破坏严格别名规则取消引用类型双关指针会破坏严格别名规则 [-Wstrict-aliasing]严格别名规则是什么?“取消引用类型双关指针将破坏严格的别名规则”警告和其他人)并且对我的警告完全感到困惑。

所以我有一个结构:

typedef struct {
    unsigned char precision;
    unsigned char scale;
    unsigned char array[33];
} DBNUMERIC;
Run Code Online (Sandbox Code Playgroud)

当从 MS SQL Server 检索数据时,该结构由 FreeTDS 库填充。我知道从array[1]那里开始是 64 位整数(大端),我想得到它。我使用以下代码:

int64_t result = 0;
result = be64toh(*((decltype(result)*)(numeric.array + 1)));
Run Code Online (Sandbox Code Playgroud)

但是 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);
Run Code Online (Sandbox Code Playgroud)

没有关于违反严格别名规则的警告。我不认为此代码与原始代码不同,因此我很困惑。如何将数组中的 8 个字节转换为int64_t变量?

Sha*_*our 5

您的两个案例都违反了严格的别名规则。根据警告和优化级别,gcc 的严格别名警告可能会出现误报和误报

如果您想以严格别名规则不允许的方式输入双关语,那么您应该只使用std::memcpy

std::memcpy(&result, numeric.array+1, sizeof(int64_t ));
Run Code Online (Sandbox Code Playgroud)

我们可以从以下来源看到;我在此处的回答中引用的这篇文章类型双关语、严格别名和优化以及关于类型双关语和联合标准讨论对话告诉我们,编译器应该足够聪明,可以优化memcpy以生成高效代码。


归档时间:

查看次数:

850 次

最近记录:

9 年,11 月 前