处理“-Wincompatible-pointer-types”警告

Dealing with an `-Wincompatible-pointer-types` warning

提问人:Kalcifer 提问时间:5/8/2022 最后编辑:Kalcifer 更新时间:5/8/2022 访问量:340

问:

我有以下导致警告的代码:-Wincompatible-pointer-types

union SensorData
{
    uint64_t raw_sensor_data;
    struct
    {
        uint16_t humidity_data;
        uint16_t temperature_data;
    };
} sensor_data;

/* ... Bunch of other code ...*/

uint8_t *raw_sensor_data_bytes = &sensor_data.raw_sensor_data;
uint8_t checksum = raw_sensor_data_bytes[0];
uint8_t sum = 0;
for (uint8_t i = 1; i < 8; i++)
{
    sum += raw_sensor_data_bytes[i];
}

这是由此产生的错误:

warning: initialization of 'uint8_t *' {aka 'unsigned char *'} from incompatible pointer type 'uint64_t *' {aka 'long long unsigned int *'} [-Wincompatible-pointer-types]
   88 |     uint8_t *raw_sensor_data_bytes = &sensor_data.raw_sensor_data;
      |                                      ^

我想我理解为什么会触发错误:这是因为我有一个指针,它期望指向一个 8 位整数,而实际上它指向一个 64 位整数;然而,这是(我目前认为的)一个很好的理由。我需要将 64 位整数拆分为 8 位段,因此我认为创建一个指针实际上将 64 位整数分成 8 个 8 位段是可以的;但是,这样做会导致上述警告。有没有更合适的方法来做我正在尝试做的事情来摆脱警告,或者我是否有可能只是以某种方式简单地覆盖警告,或者我只需要忽略它?

c 编译器-警告

评论


答:

2赞 dbush 5/8/2022 #1

将对象指针转换为指向 or(或等效项)的指针以访问对象的各个字节是明确定义的,只要转换是通过显式强制转换进行的:charunsigned char

uint8_t *raw_sensor_data_bytes = (uint8_t *)&sensor_data.raw_sensor_data;

评论

0赞 Kalcifer 5/8/2022
啊,所以转换到说该地址不再指向 64 位整数的地址,而是指向 8 位整数。在 64 位整数的位置?我仍然感到困惑的是,为什么它们似乎都工作得很好。在什么情况下,它们不起作用,从而有理由发出警告?&sensor_data.raw_sensor_data(uint8_t)&sensor_data.raw_sensor_data
0赞 dbush 5/8/2022
@Kalcifer 演员基本上会说“是的,我是故意这样做的”,尽管一般来说,您希望避免演员阵容,因为它们在某些情况下可能会掩盖真正的问题。
0赞 Kalcifer 5/8/2022
啊,好吧,这是有道理的。您能举例说明它们何时会引起问题吗?