Why void* valid in C? [duplicate] - c

This question already has answers here:
What does void* mean and how to use it?
(10 answers)
Closed 4 years ago.
Why we can decalre a variable as "void* x" but not "void x"?
Why is "void* x" useful?
example:
int main()
{
void* a;
return 0;
}
The above code compiles and runs sucessfully
int main()
{
void a;
return 0;
}
The above code gets the following compile error:
b.c:6:10: error: variable has incomplete type 'void'
void a;
^
1 error generated.

I think it is because void is generally used as a return type for functions to indicate that there is no return value.
Void* is actually incredibly useful! Void* is used as a return type for memory functions like malloc() and calloc() because it allows them to manipulate any data type. Additionally, void* can be used to create generic functions. An often cited example of this is:
void qsort (void* base, size_t num, size_t size, int (*comparator)(const void*,const void*))
This is a generic function implementing quicksort. The comparison function in this case uses void* pointers to suggest it can compare any data type.

Related

What does a variable declaration like this mean - uint32_t (* name)(something, something, something) in C [duplicate]

This question already has answers here:
How do function pointers in C work?
(12 answers)
Closed 9 years ago.
I'm learning C and I came to this expression:
void *(*routine)(void *)
I find it very confusing. Maybe it's a pointer...to a pointer... to a pointer?
If I wanted to pass this thing into a function, how would we manipulate it? I am trying to pass this routine construction as a parameter to a function that takes a void(*)(void)... but I am rather lost on what that actually means.
Start with the leftmost identifier and work your way out, remembering that absent explicit grouping with parentheses, [] and function call () bind before *, so
*a[N] is an N-element array of pointers
(*a)[N] is a pointer to an N-element array
*f() is a function returning a pointer
(*f)() is a pointer to a function
So,
routine -- routine
*routine -- is a pointer
(*routine)( ) -- to a function
(*routine)(void *) -- taking a single parameter of type void *
*(*routine)(void *) -- returning a pointer
void *(*routine)(void *) -- to void
void *(*routine)(void *);
declares a pointer to function that takes argument of type void * and returns pointer of type void *
Simple example:
#include <stdio.h>
void* foo(void* x) {
printf("Hello.");
}
int main(void) {
void *(*routine)(void *);
routine = foo; // assings foo to our function pointer
(*routine)(NULL); // invokes foo using this pointer
return 0;
}
outputs: Hello.
"If I wanted to pass this thing into a function" ~ here is example 2 for you:
#include <stdio.h>
void* foo(void* x) {
printf("Hello.");
}
typedef void *(*RoutinePtr)(void *); // alias to make your life easier
void routineInvoker(RoutinePtr routine) {
(*routine)(NULL); // invokes the routine
}
int main(void) {
RoutinePtr routine = foo; // creates a function pointer
routineInvoker(routine); // and passes it to our invoker
return 0;
}

Function as parameter to function [duplicate]

This question already has answers here:
C Why function pointer as parameter instead of just a function?
(2 answers)
Closed 6 years ago.
I just noticed that this compiles without any errors or warnings using -pedantic -Wall with both gcc and clang.
#include <stdio.h>
int x = 0;
void func(int f(const char *)) {
f("func()!");
}
int main(void) {
func(puts);
}
It appears that the parameter f is treated like pointer to function int (*)(const char *) in this case.
But this a behavior that I have never seen or heard anything about. Is this legal C code? And if so then what happens when you have a function as a parameter to a function?
It is allowed by the standard. From C99 standard chapter 6.9.1 (took from http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf):
EXAMPLE 2 To pass one function to another, one might say
int f(void);
/*...*/
g(f);
Then the definition of g might read
void g(int (*funcp)(void))
{
/*...*/
(*funcp)(); /* or funcp(); ... */
}
or, equivalently,
void g(int func(void))
{
/*...*/
func(); /* or (*func)(); ... */
}

What does void *(*routine)(void *) mean in C? [duplicate]

This question already has answers here:
How do function pointers in C work?
(12 answers)
Closed 9 years ago.
I'm learning C and I came to this expression:
void *(*routine)(void *)
I find it very confusing. Maybe it's a pointer...to a pointer... to a pointer?
If I wanted to pass this thing into a function, how would we manipulate it? I am trying to pass this routine construction as a parameter to a function that takes a void(*)(void)... but I am rather lost on what that actually means.
Start with the leftmost identifier and work your way out, remembering that absent explicit grouping with parentheses, [] and function call () bind before *, so
*a[N] is an N-element array of pointers
(*a)[N] is a pointer to an N-element array
*f() is a function returning a pointer
(*f)() is a pointer to a function
So,
routine -- routine
*routine -- is a pointer
(*routine)( ) -- to a function
(*routine)(void *) -- taking a single parameter of type void *
*(*routine)(void *) -- returning a pointer
void *(*routine)(void *) -- to void
void *(*routine)(void *);
declares a pointer to function that takes argument of type void * and returns pointer of type void *
Simple example:
#include <stdio.h>
void* foo(void* x) {
printf("Hello.");
}
int main(void) {
void *(*routine)(void *);
routine = foo; // assings foo to our function pointer
(*routine)(NULL); // invokes foo using this pointer
return 0;
}
outputs: Hello.
"If I wanted to pass this thing into a function" ~ here is example 2 for you:
#include <stdio.h>
void* foo(void* x) {
printf("Hello.");
}
typedef void *(*RoutinePtr)(void *); // alias to make your life easier
void routineInvoker(RoutinePtr routine) {
(*routine)(NULL); // invokes the routine
}
int main(void) {
RoutinePtr routine = foo; // creates a function pointer
routineInvoker(routine); // and passes it to our invoker
return 0;
}

Is main with parameter list of void different from main with an empty parameter list? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why is the type of the main function in C and c++ left to the user to define?
What is a void ? Anyone provide some examples, proper use of void ? And what is the difference when we write void main (void) or main() ?
In C, in general, (void) means no arguments required in function call, while () means unspecified number of arguments.
e.g.
void foo(void)
{
// body
}
void bar()
{
//body
}
In calling enviroment,
foo(); // Correct
foo(1); // Incorrect
bar(); // Correct
bar(1); // Also correct
This was the general explanation.
But for your case for main() , C99 Standard says that,
5.1.2.2.1 Program startup
The function called at program startup is named main. The
implementation declares no prototype for this function. It shall be
defined with a return type of int and with no parameters:
int main(void) { /* ... */ }
or
with two parameters (referred to here as argc and argv, though any
names may be used, as they are local to the function in which they are
declared):
int main(int argc, char *argv[]) { /* ... */ } or equivalent;
or
in some other implementation-defined manner.
So, in this void main(void) return type should be int.
And at last , for main(),
return type is not given so implicitly return type would be int.
Excluding the return type of the main as in
main(){
}
doesn't mean that it's a void type, it depends on the compiler. I think it can be said it's generically interpreted as
int main(){
}
The void type tells the compiler that there is no 'entity' (no 'storage'), so
void func(int i)
takes an int but returns nothing. In the case of parameters this:
void func()
is equivalent to this:
void func(void)
which indicates more explicitly that it does not take parameters.
Different story is with the type void * which is a type, a pointer to something dimensionless.
Basically, void is a data type, which basically used with method declaration. It means nothing or no type. Eg:
1) int myFunc(void) -- the function takes nothing.
2) void myFunc(int) -- the function returns nothing
3) void* data; -- 'data' is a pointer to data of unknown type, and cannot be dereferenced
Void means "emptyness". In your example of void main() it means that the functions main() does not return a value. I feel obliged tell you that void main() should be avoided (no pun intended) at all costs, use int main() instead. int main() makes sure your program can return a value of type int to the OS on close. There are numerous other uses of void, check out this website if you want to read more about this.
void is a data type with no values. It is also an incomplete data type that cannot be completed. When used as a return type for a function, it indicates that the function does not return a value:
void foo(int x);
When used as a parameter list, it indicates that the function takes no arguments:
void bar(void);
This is different from an empty parameter list, which indicates that the function takes an unspecified number of arguments (in C; in C++, an empty parameter list is the same as using void):
void bletch();
No object (variable) can be typed void. However, you can declare pointers of type void *: these are "generic" pointers, and can be converted to and from other pointer types without an explicit cast. The standard memory allocation functions malloc, calloc, and realloc all return void *:
double *darr = malloc(sizeof *darr * rows);
In a hosted implementation (basically, anything with an operating system), main must be declared as
int main(void)
or
int main(int argc, char **argv) // the parameter names can be whatever you want,
// but argc and argv are the usual convention;
// char **argv is equivalent to char *argv[]
or in some other implementation-defined manner; an implementation may accept
void main()
as a legitimate signature for main, but it must explicitly document that somewhere.

generic programming in C with void pointer

Even though it is possible to write generic code in C using void pointer(generic pointer), I find that it is quite difficult to debug the code since void pointer can take any pointer type without warning from compiler.
(e.g function foo() take void pointer which is supposed to be pointer to struct, but compiler won't complain if char array is passed.)
What kind of approach/strategy do you all use when using void pointer in C?
The solution is not to use void* unless you really, really have to. The places where a void pointer is actually required are very small: parameters to thread functions, and a handful of others places where you need to pass implementation-specific data through a generic function. In every case, the code that accepts the void* parameter should only accept one data type passed via the void pointer, and the type should be documented in comments and slavishly obeyed by all callers.
This might help:
comp.lang.c FAQ list ยท Question 4.9
Q: Suppose I want to write a function that takes a generic pointer as an argument and I want to simulate passing it by reference. Can I give the formal parameter type void **, and do something like this?
void f(void **);
double *dp;
f((void **)&dp);
A: Not portably. Code like this may work and is sometimes recommended, but it relies on all pointer types having the same internal representation (which is common, but not universal; see question 5.17).
There is no generic pointer-to-pointer type in C. void * acts as a generic pointer only because conversions (if necessary) are applied automatically when other pointer types are assigned to and from void * 's; these conversions cannot be performed if an attempt is made to indirect upon a void ** value which points at a pointer type other than void *. When you make use of a void ** pointer value (for instance, when you use the * operator to access the void * value to which the void ** points), the compiler has no way of knowing whether that void * value was once converted from some other pointer type. It must assume that it is nothing more than a void *; it cannot perform any implicit conversions.
In other words, any void ** value you play with must be the address of an actual void * value somewhere; casts like (void **)&dp, though they may shut the compiler up, are nonportable (and may not even do what you want; see also question 13.9). If the pointer that the void ** points to is not a void *, and if it has a different size or representation than a void *, then the compiler isn't going to be able to access it correctly.
To make the code fragment above work, you'd have to use an intermediate void * variable:
double *dp;
void *vp = dp;
f(&vp);
dp = vp;
The assignments to and from vp give the compiler the opportunity to perform any conversions, if necessary.
Again, the discussion so far assumes that different pointer types might have different sizes or representations, which is rare today, but not unheard of. To appreciate the problem with void ** more clearly, compare the situation to an analogous one involving, say, types int and double, which probably have different sizes and certainly have different representations. If we have a function
void incme(double *p)
{
*p += 1;
}
then we can do something like
int i = 1;
double d = i;
incme(&d);
i = d;
and i will be incremented by 1. (This is analogous to the correct void ** code involving the auxiliary vp.) If, on the other hand, we were to attempt something like
int i = 1;
incme((double *)&i); /* WRONG */
(this code is analogous to the fragment in the question), it would be highly unlikely to work.
Arya's solution can be changed a little to support a variable size:
#include <stdio.h>
#include <string.h>
void swap(void *vp1,void *vp2,int size)
{
char buf[size];
memcpy(buf,vp1,size);
memcpy(vp1,vp2,size);
memcpy(vp2,buf,size); //memcpy ->inbuilt function in std-c
}
int main()
{
int array1[] = {1, 2, 3};
int array2[] = {10, 20, 30};
swap(array1, array2, 3 * sizeof(int));
int i;
printf("array1: ");
for (i = 0; i < 3; i++)
printf(" %d", array1[i]);
printf("\n");
printf("array2: ");
for (i = 0; i < 3; i++)
printf(" %d", array2[i]);
printf("\n");
return 0;
}
The approach/strategy is to minimize use of void* pointers. They are needed in specific cases. If you really need to pass void* you should pass size of pointer's target also.
This generic swap function will help you a lot in understanding generic void *
#include<stdio.h>
void swap(void *vp1,void *vp2,int size)
{
char buf[100];
memcpy(buf,vp1,size);
memcpy(vp1,vp2,size);
memcpy(vp2,buf,size); //memcpy ->inbuilt function in std-c
}
int main()
{
int a=2,b=3;
float d=5,e=7;
swap(&a,&b,sizeof(int));
swap(&d,&e,sizeof(float));
printf("%d %d %.0f %.0f\n",a,b,d,e);
return 0;
}
We all know that the C typesystem is basically crap, but try to not do that... You still have some options to deal with generic types: unions and opaque pointers.
Anyway, if a generic function is taking a void pointer as a parameter, it shouldn't try to dereference it!.

Resources