-1

I'm trying to compile a third party library, but for some reason I'm getting an error. The library is likely compiled differently. I've read up on the error but I can't seem to figure out what the issue is! :(

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;
}

The error is as follows:

 sfo.cpp:150:47: error: arithmetic on a pointer to void
         entry_table = (struct sfo_table_entry*)(data + sizeof(*hdr));
                                                 ~~~~ ^
Cfun
  • 8,442
  • 4
  • 30
  • 62
Appel Flap
  • 261
  • 3
  • 23
  • 1
    Does this answer your question? [Pointer arithmetic for void pointer in C](https://stackoverflow.com/questions/3523145/pointer-arithmetic-for-void-pointer-in-c) – Thomas Jager May 29 '20 at 18:32
  • 1
    You can't do pointer arithmetic on `void*`, you need to cast it into some other recognizable type, for your case it should be `char*`: `(struct sfo_table_entry*)((char*)data + sizeof(*hdr));` – Ruks May 29 '20 at 18:33
  • Some implementations will give the size as `1` but it is undefined. The target type is not known. – Weather Vane May 29 '20 at 18:34
  • I appreciate all the input, everyone. Casting it to `char *` indeed works. The given info is very informative for my case. – Appel Flap May 29 '20 at 18:42

3 Answers3

2

The error is that arithmetic is not allowed on pointers of type void *, nor on pointers to any other incomplete type. This is consistent with the fact that pointer arithmetic is defined in terms of the size of the pointed-to type, which is unknown for incomplete types.

Some compilers implement an extension that would apply here, treating pointer arithmetic on void * as if the pointed-to type had size 1. Often, this is exactly what the author of the code intended, as appears to be the case in your code. In that event, you could consider fixing this flaw in the code by changing the affected line to

    entry_table = (struct sfo_table_entry*)((char *)data + sizeof(*hdr));
John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • Still not perfect/portable, though. Assigning the pointer to `entry_table` may run into memory alignment issues. That's why one would normally allocate memory for `entry_table` (e.g. automatically or using `malloc`) and `memcpy` from `*( (char *)data + sizeof(*hdr) )` into this memory block. Might be good enough for the OP (though performance may suffer). – ikegami May 29 '20 at 19:43
1

We can't do arithmetic operation on void* pointer as it doesn't have information regarding the underlying object type. Cast to appropriate pointer type and do arithmetic on it.

Sreeraj Chundayil
  • 5,548
  • 3
  • 29
  • 68
1

From the C Standard (6.2.5 Types)

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

To perform the pointer arithmetic there is required the size of the pointed object.

Some compilers allows to use pointers to void in the pointer arithmetic setting the size of the pointed object equal to the sizeof( char ) that is to 1.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335