【问题标题】:Arithmetic on a pointer to void error when compile a third party library编译第三方库时指向 void 错误的指针的算术
【发布时间】:2020-05-29 18:28:26
【问题描述】:

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

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));
                                                 ~~~~ ^

【问题讨论】:

  • 这能回答你的问题吗? Pointer arithmetic for void pointer in C
  • 你不能在void*上做指针运算,你需要把它转换成其他可识别的类型,你的情况应该是char*:(struct sfo_table_entry*)((char*)data + sizeof(*hdr));
  • 一些实现会将大小设为1,但它是未定义的。目标类型未知。
  • 感谢大家的意见。将其转换为 char * 确实有效。给定的信息对我的情况非常有用。

标签: c compiler-errors void-pointers


【解决方案1】:

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

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

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

【讨论】:

  • 虽然仍然不完美/便携。将指针分配给entry_table 可能会遇到内存对齐问题。这就是为什么通常会为entry_table(例如自动或使用malloc)和memcpy*( (char *)data + sizeof(*hdr) )分配内存到这个内存块的原因。对于 OP 来说可能已经足够好了(尽管性能可能会受到影响)。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    来自 C 标准(6.2.5 类型)

    19 void 类型包含一组空值;这是一个不完整的 无法完成的对象类型。

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

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

    【讨论】:

      猜你喜欢
      • 2014-04-09
      • 1970-01-01
      • 2020-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-03
      相关资源
      最近更新 更多