What exactly does void * mean - c

I have seen void * explained as a pointer to an unused chunk of memory. I have also seen void * described as a pointer to any type, or a pointer to any type can be cast to void *.
From what I know, int * means a pointer to type int. So keeping this in mind, what does void * mean literally? Is it a pointer to type void? This doesn't seem right because I did not know that void could be a type.

void * is a pointer to void.
C11: 6.3.2.3 Pointers:
A pointer to void may be converted to or from a pointer to any object type. A pointer to
any object type may be converted to a pointer to void and back again; the result shall
compare equal to the original pointer.
The compiler will not let you dereference a void* pointer because it does not know the size of the object pointed to but you need to cast void * type pointer to the right type before you dereference it.

Let's begin with this example:
int a = 65;
int *q = &a;
void *p = q;
char *c = p;
(source: qiniudn.com)
we define an int variable a, and an int pointer q pointing to it. p in the void * pointer.
The beginning address of a is 0x8400(just for simplicity).
A pointer is an address, no more.
No matter what type of pointer, they have the same memory size, and their value is an address.
So,
printf("%p, %p", *p, *q);
will display:
0x8400, 0x8400
Type: how you interpret the date
As you see in the graph, the data in memory is 65000000(this is little endian). If we want to use it, we have to specify what it is! And type does that.
printf("%d %c", *p, *q);
If we print it as integer, we get 65. If we print them as char, we get A(asciicode).
And p + 1 pointer to 0x8401, q + 1 points to 0x8404.
void *: a universal type
According to wikipedia:
A program can probably convert a pointer to any type of data (except a function pointer) to a pointer to void and back to the original type without losing information, which makes these pointers useful for polymorphic functions.
Yes, void * define a trivial unit of pointer, it can be converted to any pointer and vise versa. But you can't dereference it, because it doesn't specify a type.
If you want to manipulator on bytes, you should always use void *.
Isn't char * the same as void *
Not exactly.
The C language standard does not explicitly guarantee that the different pointer types have the same size.
You can't always hope char * have the same size on different platforms.
And converting char * to int * can be confusing, and mistakes can be made.

It means: a pointer to some memory, but this pointer does not contain any information about the type of data that may be stored in that memory.
This is why it's not possible to dereference a void *: the operation of dereferencing (and obtaining an rvalue, or writing through an lvalue) requires that the bits in the memory location be interpreted as a particular type, but we don't know which type to interpret the memory as.
The onus is on the programmer to make sure that data read in matches the type of data read out. The programmer might help himself in this by converting the void * to a pointer to an object type.
It's useful if you want to have a common interface for dealing with memory of multiple possible types, without requiring the user to do a lot of casting. for example free() takes a void * because the type information isn't necessary when doing the free operation.

void * is a pointer to data of unspecified type. As such, it can't be used directly; it must be cast to a usable datatype before it can be dereferenced.

Related

Pointers Question - What does (double*)params mean?

I'm having a bit of trouble in understanding this piece of code.
double F(double k,void *params){
double *p=(double *)params;
return p[0];
}
I have only a small notion of pointers from a class, and I understand that in the function his using the pointer *params as an argument. I also understand that he uses double *p to declare the variable. What I can't figure out is what (double *)params do, or how p got turned into a vector.
The expression (double *)params means "treat params as a pointer to double instead of a pointer to void". The (double *) is a cast.
Under most circumstances you cannot copy a pointer value of one type to a pointer variable of a different type (you can't assign a double * value to an int * variable) without an explicit cast.
The one exception in C is assigning a void * value to a different pointer type or vice versa - in this particular case, the cast is unnecessary. However, C++ does not allow implicit conversion from void * to other pointer types, so in that language the cast is necessary.
Pointers to different types do not have to have the same size and representation; the only rules are
char * and void * have the same size and alignment;
Pointers to qualified types have the same size and alignment as pointers to the unqualified equivalent (e.g., const int * and volatile int * have the same size and alignment as int *);
Pointers to all struct types have the same size and alignment;
Pointers to all union types have the same size and alignment;
(double *)params instructs the compiler to think of params (which is a void pointer originally - the compiler has no idea what type it's pointing to) as a pointer to a double only while processing this expression. It's very commonly known as a "C-style cast of one type to another". In this case, we are "casting" params from a void* type to a double* type, since we are storing it in the pointer to double double *p.
Without the cast, the compiler will most likely give you a type mismatch error/warning, since you would be trying to store the value of a void pointer into a pointer to double.
More specifically, when you have a double pointer, or pointer to anything except void, the compiler associates a number with it in order to be able to perform pointer arithmetic on it when you write something like (ptr++). For example, when doing (++ptr) on a pointer to double, the compiler knows how many bytes to go up by, because it knows the size of a double. However, a void* has no size associated with it, therefore the compiler can't perform pointer arithmetic on it. So when casting the void pointer to a double pointer using (double*)params, you're allowing the compiler to associate the standard size of variables of type double with whatever this void pointer is pointing to only while processing this expression, for the purposes of storing its value inside an actual pointer to double. After the compiler is done reading this expression, it goes back to thinking params is a void pointer, not a double pointer, ie the effect of casting it to a double pointer is not permanent, it's only valid during the processing of this expression by the compiler.

Can we dereference a void pointer without knowing its type?

I have a question regarding the void pointer in c language. I would like to know Can we dereference a void pointer without knowing its type?
No, because you don't know how to interpret the data contained by the corresponding memory space. Memory itself has no type, and it is pointers that contains the type information. For example, memory pointed to by int * is interpreted as an int.
When dereferencing a void *, there is no way for the compiler to tell which type bytes starting from that address should be interpreted as. It can be a double, an unsigned long, or even an array of chars.
However, it is possible to get dereference a void * through casting, because the cast operator contains the information about object type.
No, A void pointer can be dereferenced only after explicit casting. For example:
int a = 5;
void *b = &a;
printf(“%d\n”, *((int*)b));
TL;DR No, you can't.
While dereferencing a pointer-to-type, you generate an "object" of the type.
Since a void is not a complete type, you cannot dereference a void* directly. That is why, you need to either
copy the pointer to another pointer of a complete type
cast the pointer to another complete type
and then, you can dereference to get the object of the new complete type.
You cannot. Dereferencing a void pointer requires an explicit cast beforehand.
You can ofcourse cast it to any particular type and then dereference it without knowing its original type, but why you would want to do that is beyond me.

Can you ever assume typecasting pointers is safe?

I've heard from many people that you cannot guarantee typecasting will be performed lossless. Is that only true if you don't know your processor, that is, you haven't verified the number of bytes used for your data types? Let me give an example:
If you execute the following:
typedef struct
{
int i;
char c;
float f;
double d;
} structure;
size_t voidPtrSz = sizeof(void *);
size_t charPtrSz = sizeof(char *);
size_t intPtrSz = sizeof(char *);
size_t floatPtrSz = sizeof(float *);
size_t doublePtrSz = sizeof(double *);
size_t structPtrSz = sizeof(structure *);
size_t funcPtrSz = sizeof(int (*)(float, char));
printf("%lu\n", voidPtrSz);
printf("%lu\n", charPtrSz);
printf("%lu\n", intPtrSz);
printf("%lu\n", floatPtrSz);
printf("%lu\n", doublePtrSz);
printf("%lu\n", structPtrSz);
printf("%lu\n", funcPtrSz);
…and the output is the following…
4
4
4
4
4
4
4
Can you assume that in all cases you can typecast a specific data type pointer to another data type pointer safely? For example, if you execute this:
int foo(float, char)
{
}
void *bar(void)
{
return (void *)foo;
}
int (*pFunc)(float, char) = bar();
Can you assume with certitude that pFunc has the address of foo?
Regarding your specific code example, let's refer to section 6.3.2.3 of the C99 language standard:
A pointer to void may be converted to or from a pointer to any incomplete or object type. A pointer to any incomplete or object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer.
Note that a pointer-to-function is not the same as pointer-to-object. The only mention of pointer-to-function conversions is:
A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall compare equal to the original pointer. If a converted pointer is used to call a function whose type is not compatible with the pointed-to type, the behavior is undefined.
So your code example invokes undefined behaviour.
If we avoid function-pointer conversions, the following paragraph explains everything:
A pointer to an object or incomplete type may be converted to a pointer to a different object or incomplete type. If the resulting pointer is not correctly aligned for the pointed-to type, the behavior is undefined. Otherwise, when converted back again, the result shall compare equal to the original pointer.
Note: Converting between pointer types is a separate issue from converting and then dereferencing (in general, that's only valid if you're converting to char * and then dereferencing.)
Can you assume that in all cases you can typecast a specific data type pointer to another data type pointer safely?
Any data pointer can be safely cast to char* or void*. Any char* or void* thus created can be cast back to its original type. Any other data pointer cast leads to undefined behavior when indirection is performed on the pointer.
Any function pointer type can be cast to any other function pointer type, although you should not call a function through the wrong type. Casting a function pointer to void* or any other data pointer type results in undefined behavior.
Is that only true if you don't know your processor, that is, you haven't verified the number of bytes used for your data types?
Even then, you're not safe. When the C standard says a construct has undefined behavior, compiler writers are free to handle the construct as they wish. The result is that even though you think you know a construct with UB will be handled because you know the target CPU, optimizing compilers may cut corners and generate very different code than you expect.
#Oli Charlesworth gives you a great answer.
I hope I can shed a little light on what pointer are so you can better understand pointer mechanics:
A pointer is an address. This address is the address of the first byte of your data. The type of the pointer specifies how many bytes starting from that first byte are part of the data and how those bytes encode the data.
For instance, on gcc x86, if you have a int * p, the value held by p tells the starting address of data, and the type of p (int *) tells that at that address he will interpret 4 bytes (in little endian byte-order) in two's complement signed number representation.
A void * pointer is a "generic pointer". The pointer still holds an address, but the pointer type doesn't specify what kind of data you find there, or even how many bytes form the data, so you can never access data through a void * pointer, but as answered before, you can safely convert between a pointer to void and a pointer to any incomplete or object type.
A pointer to function holds the address of a function, and the type of the pointer tells how to call that function (what parameters and of what kind) and what the function returns.

can a void pointer safely point to annother pointer?

This might be obvious but, can a void pointer safely point to another pointer? i.e. point to a type int *
int i = 5;
int *ip = &i;
void *vp = &ip;
int *nip = *(int **)vp;
int ni = *nip; // == 5?
EDIT: Sorry maybe I'm not being clear, I would like to know if a void pointer can POINT TO a section of memory that has the type of another pointer; without being a void **. just void *
Yes, you can convert any object pointer to void * and back to the original pointer type without loss of information.
From the horse's mouth:
(C99, 6.3.2.3p1) "A pointer to void may be converted to or from a pointer to any incomplete or object type. A pointer to any incomplete or object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer."
Yes, it can point to any object type1. You can't actually dereference a void pointer since the compiler doesn't know the "real" type behind it. But the pointing aspect is fine.
From C11 6.3.2.3 Pointers /1:
A pointer to void may be converted to or from a pointer to any object type. A pointer to any object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer.
1/ "Object type" does not include functions, the rules for converting function pointers are slightly more restrictive.

Confusion regarding a function definition in C

I found this function definition
void *func(void *param) {
}
Actually, I have a certain confusion regarding this function definition. What does void * mean in the return type of the function as well as the argument. I am a beginner in C. So please don't mind. Thank you
void *func(void *param) {
int s = (int)param;
....
}
Well looking at the above program which I found. I think it should have been
int *s = (int *)param;
isn't it? I am confused
void * means it's a pointer of no specific type, think of it as a generic pointer, unlike say int * an int pointer.
You can cast it into a different type if need be (for instance if you are going to do pointer arithmetic with the pointer).
You might find this SO question of use: Concept of void pointer in C programming
It simply means that the function func takes one parameter which is a pointer (to anything) and returns a pointer (to anything). When you use a void *, you are telling the compiler "this is a pointer, but it doesn't matter at this point what it's a pointer to".
When you want to actually use the data it's pointing to, you need to cast it to a pointer to some other type. For example, if it points to an int, you can create an int * variable and dereference that:
int *int_ptr = (int *)param;
// now (*int_ptr) is the value param is pointing to
you can think of it as a raw pointer, nothing more than an address, think about it, pointers are nothing more than address right, so they should all be of equal size, either 32 or 64 bits in most modern systems but if thats the case why do we say int * or char * or so on if they are all the same size, well thats because we need of a way to interpret the type we are pointing to, int * means when we dereference go to that address and interpret the 4 bytes as an int or char * means when we dereference go to that address and get a byte, so what happens when you dereference a void * well you get warning: dereferencing ‘void *’ pointer basically we really can't and if you do its affects are compiler dependent, the same applies when we do arithmetics on it.
So why bother using them? well I personally don't and some groups dont particularly like them, fundamentally they allow you to create fairly generic subroutines, a good example would be memset which sets a block of memory to a certain byte value, its first argument is a void * so it won't complain whether giving a char * or int * due note that it works on a per byte basis, and you need to properly calculate the total size of the array.
void *func(void *param) {
}
param is a void pointer means it is a pointer of any reference type. since a void pointer has no object type,it cannot be dereferenced unless it is case.
so void *param;
int *s=(int*)param;
here since param is an pointer variable so you will have to cast it as a pointer variable.not to a int type as you did there.
e.g.
int x;
float r;
void *p=&x;
int main()
{
*(int *)p=2;
p=&r;
*(float*)p=1.1;
}
in this example p is a void pointer. now in main method I have cast the p as a int pointer and then as a float pointer so that it can reference to first a integer and then a float.
Returning a pointer of any type. It can be of any datatype.

Resources