假设我有一个字节缓冲区:
char buffer[] = { 0x11, 0x00, 0x00, 0x02, .... };
我想做的是从一个特定的偏移量中取出一个 qword。偏移量将以字节为单位计算。 这是我所做的:
unsigned long long *ptr = &buffer[16];
unsigned long long myqword = *ptr;
这似乎对我有用。我从头开始跳过 16 个字节,然后取 8 个字节。
我的问题是为什么我会收到此警告消息:
warning: initialization of ‘long long unsigned int *’ from incompatible pointer type ‘char *’ [-Wincompatible-pointer-types]
unsigned long long *ptr = &buffer[16];
最佳答案
这里有4个主要问题:
unsigned long long*
与char*
不兼容。这是编译器错误的原因。- 通过
unsigned long long*
读取一堆char
会违反 strict aliasing rule ,调用未定义的行为错误。 - 通过
unsigned long long*
读取一堆char
也可能导致未对齐的访问,调用未定义的行为错误。 - 使用
char
来存储整数值是一个非常糟糕的主意,因为char
具有实现定义的签名并且可以在某些计算机上签名。请改用uint8_t
。
您应该改为使用 memcpy:
size_t n = sizeof(unsigned long long);
memcpy(&myqword, &buffer[i * n], n);
如果您确实需要访问特定内存位置的内容而不复制它,您别无选择,只能创建一些新类型,例如 union :
#include <inttypes.h>
#include <stdio.h>
typedef union
{
uint8_t byte [8];
uint64_t qword;
} qword_t;
int main (void)
{
qword_t q = {.byte = {0x11, 0x00, ...} };
printf("%"PRIu64, q.qword);
}
但请注意,此代码取决于 CPU 字节序,不可移植。
关于C指针转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52382272/