编译第三方库时指针指向void错误的运算

Arithmetic on a pointer to void error when compile a third party library

我正在尝试编译第三方库,但由于某种原因出现错误。该库可能以不同方式编译。我已经阅读了错误,但我似乎无法弄清楚问题是什么! :(

struct sfo_entry {
    char* key;
    size_t size;
    size_t area;
    void* value;
    enum sfo_value_format format;
    struct sfo_entry* next;
    struct sfo_entry* prev;
};

struct sfo {
    struct sfo_entry* entries;
};

bool sfo_load_from_memory(struct sfo* sfo, const void* data, size_t data_size) {
    struct sfo_header* hdr;
    struct sfo_table_entry* entry_table;
    struct sfo_table_entry* entry;

    entry_table = (struct sfo_table_entry*)(data + sizeof(*hdr));

    // ...

    return true;
}

错误如下:

 sfo.cpp:150:47: error: arithmetic on a pointer to void
         entry_table = (struct sfo_table_entry*)(data + sizeof(*hdr));
                                                 ~~~~ ^

我们不能对 void* 指针进行算术运算,因为它没有关于底层对象类型的信息。转换为适当的指针类型并对其进行算术运算。

来自 C 标准(6.2.5 类型)

19 The void type comprises an empty set of values; it is an incomplete object type that cannot be completed.

要执行指针运算,需要指针对象的大小。

一些编译器允许在指针算法中使用指向 void 的指针,设置指向对象的大小等于 sizeof( char )1

错误是不允许对类型 void * 的指针进行算术运算,也不允许对指向任何其他不完整类型的指针进行算术运算。这与指针算法是根据所指向类型的大小定义的事实一致,对于不完整的类型这是未知的。

一些编译器实现了适用于此的扩展,将 void * 上的指针算术视为指向的类型的大小为 1。通常,这正是代码作者的意图,正如出现的那样在您的代码中就是这种情况。在这种情况下,您可以考虑通过将受影响的行更改为

来修复代码中的此缺陷
    entry_table = (struct sfo_table_entry*)((char *)data + sizeof(*hdr));