Home > Software design >  Why any type can be assigned void* but I can not return void* for any type function?
Why any type can be assigned void* but I can not return void* for any type function?

Time:05-21

Why can I make for example

void *j;
int *intpointer = j;

But I can not make

int ** function(){
    void **j;
    return j;
}

I understand that for example that void* a = "any type" because void* accepts any type,, but why for example any type like int* can be assigned a void* type? If it is int* it should be assigned int* type, why does it accept void * type? I am trying to understand this:

 void *j;
 int* a = j

CodePudding user response:

void is an incomplete type; it does not specify an integer type, a floating-point type, a structure type, or any other specific type. It is largely a placeholder.

void * is a pointer to void. By pointing to void, we leave it open what a pointer points to. So a void * could be an address that was derived from an int, from structure, or from any other object type.

So void * is not an incomplete type. It is some sort of pointer type.

When a void * is assigned to an int *, the C standard says an implicit conversion is done, because a void * could be pointing to an int.

Note that void * and int * are significantly different types. void * could be pointing to any object type, but int * should point to an int. The C standard even allows a void * and an int * to have different sizes.

In turn, this means that pointing to a void * and pointing to an int * are different. So, when a void ** is assigned to an int *, this violates a constraint in the C standard. The void ** should be pointing to a void *. The void ** should not be pointing to an int *.

CodePudding user response:

In C the void * is indeed the any type. So when you assign a void* to an int* then the compiler assumes you know what you are doing. Switching pointers to void and back happens quite a lot in generic programming or every time you malloc() or free() and C programmers are lazy. They don't want to cast that case every time.

Note: A frequent pattern for this is that an int* gets passed to a function accepting a void* and then passed to a callback that casts it back to int * because it knows that it originally was an int*. Similar for generic storage containers. You put in an int* by changing it to void* so when you get it back out you change it back to int*.

Note: it is important that you only assign a void* to int* when you know it is pointing at an int, i.e. it was previously changed from int* to void*. Otherwise you enter undefined behavior territory.

Even for other pointer types C assumes you know what you are doing and it is only a warning:

<source>:2:12: warning: returning 'short int *' from a function with incompatible return type 'int *' [-Wincompatible-pointer-types]

In those case the compiler (gcc here) wants you to explicitly cast the pointer before returning to signal that this was intentional. Because it is very rare that this actually makes sense.

If you get errors for any of this then you are likely trying to compile the source as C and not C.

  •  Tags:  
  • c
  • Related