C中可疑的指针到指针转换(区域太小)

时间:2015-06-04 14:56:37

标签: c pointers lint

uint8_t *buf;
uint16_t *ptr = (uint16_t *)buf;

我觉得上面的代码是正确的,但我得到“可疑的指针到指针转换(区域太小)”Lint警告。有谁知道如何解决这个警告?

3 个答案:

答案 0 :(得分:2)

恕我直言,根本不要指挥指针。它改变了方式(表示)一个变量(和相应的内存)的访问,这是非常有问题的。

如果必须,请改为投射

答案 1 :(得分:0)

你的代码中存在问题

uint8_t buf 中,您必须为其分配一个8位长的存储区

然后在行 uint16_t * ptr =(uint16_t *)buf; 您尝试将其分配给将以16位访问它的指针。

当您尝试使用 ptr 变量进行访问时,您将获得超出分配给您的内存及其未定义行为的内存。

答案 2 :(得分:0)

这里的问题是strict aliasing。想象一下,当你遇到这样的情况时:

uint8_t  raw_data [N]; // chunk of raw data

uint16_t val = 1;
memcpy(raw_data, &val, sizeof(val)); // copy an uint16_t into this array

uint16_t* lets_go_crazy = (uint16_t*)raw_data;
*lets_go_crazy = 5;

print(raw_data);

假设print函数打印所有字节值。然后,您可能会认为前两个字节已更改为包含机器对包含值5的uint16_t的表示。不一定如此。

因为另一方面编译器可以自由地假设你从来没有修改过memcpy之后的raw_data数组,因为uint16_t不允许别名一个uint8_t。因此,它可能会将整个代码优化为:

uint8_t  raw_data [N]; // chunk of raw data

uint16_t val = 1;
memcpy(raw_data, &val, sizeof(val)); // copy an uint16_t into this array

print(raw_data);

将会发生什么是未定义的,因为严格的别名被破坏了。

虽然请注意,如果且仅当您的代码可能保证您的特定编译器不会对您拥有的任何场景应用严格别名时,您的代码可能完全正常。有些编译器选项可以在某些编译器上禁用它。

或者,您可以使用指向包含uint16_t的结构或联合的指针,在这种情况下,别名不适用。