General-purpose pointer type --void *

There is a general-purpose pointer type "void *" as a pointer type to which any pointer type can be assigned.

void *

General-purpose pointer type sample

This is a general-purpose pointer type sample.

Assignment to a general-purpose pointer and vice versa

malloc function and calloc function return a value of type "void *" .. Let's actually declare a variable of type "void *" and assign it to another pointer type.

Let's also try assigning another pointer type to the "void *" type.

#include <stdint.h>
#include <stdlib.h>

int main (void) {
  
  void * memory_block1 = malloc (sizeof (int32_t) * 10);
  void * memory_block2 = calloc (sizeof (int32_t), 10);
  
  int32_t * nums1 = memory_block1;
  int32_t * nums2 = memory_block2;

  void * memory_block1_again = nums1;
  void * memory_block2_again = nums2;
}

In C, no explicit cast is required to assign a void * type to another pointer type or to another pointer type.

Save int32_t type value in general pointer type variable

This is a tricky method, but you can store a value of type int32_t in a variable of general-purpose pointer type. This trick can be used when "I implemented an array element with void * type, but uh, I want to save an integer as well, how do I do it?"

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>

int main (void) {
  
  // void * Array with type as element
  void ** objects = calloc (sizeof (void *), 10);
  
  // Save int32_t type value in void * type element
  int32_t num = 5;
  
  // Cast int32_t type to intptr_t, then convert to void * and assign
  objects [1] = (void *) (intptr_t) num;
  
  // Cast void * type to intptr_t, then cast to int32_t type and get
  int32_t num2 = (int32_t) (intptr_t) objects [1];
  
  printf("%d\n", num2);
}

The point is to insert a cast of intptr_t type that is compatible with "void * type" and also compatible with signed integer type.

If you use this trick technique, please note that int32_t is used to work in both 32bit and 64bit environments. If you use int64_t, it will not work properly in a 32bit environment. The unsigned 32-bit integer type uint32_t can be used without any problem.

If you want to save floating point, float is 32bit wide, so it's OK. double is 64bit wide, so it's out.

void of void type and void of type * have the same meaning?

No, the void type void is a special type that means "doesn't exist".

On the other hand, the void part of "void * type" means "general purpose (any type)".

What do you think about the explicit cast from void * to other point types?

What do you think about the explicit cast from void * to other point types?

It's written as follows.

  void * memory_block1 = malloc (sizeof (int32_t) * 10);
  int32_t * nums1 = (int32_t *) memory_block1;

This is not specifically required by the C language specification. On the other hand, the C ++ specification requires it.

If you don't need to be aware of C ++, it's verbose for the C language.

It's verbose, but I don't think it would have a particularly bad effect if it was written.

Even if I write it, I don't think it has a particularly positive effect.

It's a field that tends to get caught up in linguistic controversy, but in practice, I don't think it's that much of a concern.

Associated Information