Arithmeti c для указателя на недействительную ошибку при компиляции сторонней библиотеки - PullRequest
0 голосов
/ 29 мая 2020

Я пытаюсь скомпилировать стороннюю библиотеку, но по какой-то причине выдает ошибку. Скорее всего, библиотека скомпилирована иначе. Я прочитал об ошибке, но не могу понять, в чем проблема! : (

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

Ответы [ 3 ]

2 голосов
/ 29 мая 2020

Ошибка в том, что арифметика c не разрешена ни для указателей типа void *, ни для указателей на любой другой неполный тип. Это согласуется с тем фактом, что арифметика указателя c определяется в терминах размера указанного типа, который неизвестен для неполных типов.

Некоторые компиляторы реализуют расширение, которое будет применяться здесь, обрабатывая арифметический указатель c на void *, как если бы указываемый тип имел размер 1. Часто это именно то, что задумал автор кода, как, по-видимому, имеет место в вашем коде. В этом случае вы можете подумать об исправлении этого недостатка в коде, изменив затронутую строку на

    entry_table = (struct sfo_table_entry*)((char *)data + sizeof(*hdr));
1 голос
/ 29 мая 2020

Из стандарта C (Типы 6.2.5)

19 Тип void содержит пустой набор значений; это неполный тип объекта, который не может быть завершен.

Для выполнения арифметики указателя c требуется размер указанного объекта.

Некоторые компиляторы позволяют использовать указатели аннулировать в указателе arithmeti c, устанавливая размер заостренного объекта равным sizeof( char ), то есть 1.

1 голос
/ 29 мая 2020

Мы не можем выполнить арифметическую операцию c над указателем void*, поскольку он не имеет информации о базовом типе объекта. Привести к соответствующему типу указателя и произвести на нем арифметические операции c.

...