What is the purpose of void * array = * (void **) member + siz * (* p_n);

I am trying to get a protobuf-c example compiled using the C90 compiler (MS VS2012).

There are two C99-specific things in the protobuf-c source code that can be easily changed to be compatible with C90, i.e. declaring a variable in the middle of the scope ( not allowed in C90 ) and creating structures through . -syntax (for example, some_struct_type name = {.a=1,.b=2} ).

Now I am stuck in one compilation error. The corresponding line in the protobuf-cc source file reads:

 void *array = *(void **) member + siz * (*p_n); 

Where member defined as void * and p_n as size_t * . And the corresponding error

 error C2036: 'void *' : unknown size 

Note that this is valid for protobuf-c version 1.0.1 (see the corresponding source code , line 2404). This line was changed in version 1.0.2 to

 void *array = *(char **) member + siz * (*p_n); 

with this comment . Thus, changing the line eliminates a compilation error.

My questions:

  • I would like to understand this line of code.
  • Can I upgrade to version *(char **) ?
  • What is an error message telling me?

(For some other reason, I want to stick with protobuf-c 1.0.1)

+6
source share
2 answers

passed as member is the address of a pointer to a char pointer. First, personality and deferral receive this pointer. (The address of the pointer is passed so that the pointer can be changed in a function.)

Adding siz * (*p_n) increments the pointer to the correct element.

The entire line can be rewritten as:

 char** pm = member ; char* m = *pm ; void *array = m + siz * (*p_n); 

The change from void * to char * is done in such a way that pointer arithmetic is possible, since C Standard does not allow it to indicate void pointers. The error message tells you that the size of the void * object indicates unknown, there you need to use the char * pointer.

As long as the object passed to the function is of type char** , you can upgrade to the version of char **.

+4
source

I would like to understand this line of code.

The code does pointer arithmetic and tries to hide the details. Therefore, it uses void wherever the pointer is put off. It is assumed that sizeof (*(void*)) is equal to one.

Can I switch to the *(char **) version?

Yes, because the code assigns the resulting pointer and does not cause pointer markup.

What is the error message telling me?

This hack is specific to the compiler. Your compiler does not detect this; it does not provide the void* target size.

You must use the "portable" version. sizeof(char) is one of the majority of compilers, and it is portable for these compilers.

+2
source

Source: https://habr.com/ru/post/977028/


All Articles