C: what is a void* besides a pointer? - c

Reading CMU's OS Course Home Page, they say:
"It is a good idea to be familiar with C conventions. For example, it is not generally the case that a void * is a pointer. If seeing a void * parameter, or a void ** parameter, in a function prototype would be confusing, this would be a good area to look into."
I honestly have no idea what they mean by this, what is a void * if not a pointer?

One case where void * is not a pointer involves passing data to a callback function. Imagine some library gives you a function which does some useful work, and calls your function (callback) in the middle of that work.
// useful_header.h
int do_useful_work(int data1, int data2, int (*callback)());
You call this function like this:
// your_code.c
int my_callback()
{
...
return 42;
}
int main()
{
int useful_result = do_useful_work(2, 3, my_callback);
}
What if you want to pass data to your callback? The company which provides do_useful_work doesn't know which data your callback wants to get. So it provides the most generic thing - void *. Your callback interprets it as a pointer to your struct.
// useful_header.h
int do_useful_work(int data1, int data2, int (*callback)(void *), void *user_data);
// your_code.c
struct MyData
{
int x, y, z;
};
int my_callback(void *pointer)
{
struct MyData *data = pointer;
...
return data->x + data->y + data->z + 42;
}
int main()
{
struct MyData data = {5, 6, 7};
int useful_result = do_useful_work(2, 3, my_callback, &data);
}
This has an edge-case: what if your callback wants to receive only a small item (of type int), and not a whole struct? Then you could interpret the pointer as int.
// your_code.c
int my_callback(void *not_really_pointer)
{
int data = (int)not_really_pointer;
...
return data + 42;
}
int main()
{
int useful_result = do_useful_work(2, 3, my_callback, (void *)5);
}
Here, the void * argument is not really a pointer - it's a number, which is passed using void * type because C enforces type-checking.
Having said that, this is an example of sloppy coding; making a struct with one element would be clearer here.

Related

Pthread struct argument with void*

Hy,
I was wondering if something like this is possible, without using heap(malloc/calloc) Suppose I have a struct
like this:
typedef struct {
void* par1_;
void* par2_;
}parameters;
and another one for position:
typedef struct {
short x;
short y;
}position;
This is a function that gets called by the thread.
void* car(void* arg)
{
parameters car_type = *((parameters*) arg);
int first_par = *(int*)&car_type.par1_;
int second_par = *(int*)&car_type.par2_; // can I do this?
//if yes how do I extract now values from position struct "pos.x and pos.y"
}
From my main thread I want to mark position in the struct "position", assign that struct to the second parametar "par2_", and than send that to my function car.
int main()
{
parameters pars;
position pos;
pos.x = 44;
pos.y = 25;
pars.par1_ = (void*) CAR_TYPE; // Global Variable
pars.par2_ = &pos; // not sure about this?
pthread_t tid;
pthread_create(&tid, NULL, car, (void*) &pars);
pthread_join(tid, NULL);
I'm sorry if this is a stupid question. Obviously I'm new to all this. Once again, I do not want to use heap. This is minimal example of my program.
I think you want something more like this;
void* car(void* arg)
{
parameters car_type = *((parameters*) arg);
int first_par = car_type.par1_; // This is CAR_TYPE is it really an int?
position *second_par = (position *)car_type.par2_;
second_par->x, second_par->y;
}
Although you might just want to change your parameters struct to include the types you really want.
typedef struct {
int par1_;
position* par2_;
}parameters;
void* car(void* arg)
{
parameters car_type = *((parameters*) arg);
int first_par = car_type.par1_; // This is CAR_TYPE is it really an int?
car_type.par2_->x; //access like this
}
Not sure what you're asking, so I'll give you standard advice that seems like it pertains to the situation.
Lifetime
Be very careful when passing pointers to stack memory. Always keep these three things in mind:
What will use the pointer?
What will it be used for? Which functions will end up with it? You'll need to know this to deal with the next two points.
Where will the pointer be stored?
If the pointer never leaves the stack, it's fine. If the pointer gets stored in heap memory, which has a chance of outliving the stack frame, alarm bells. If the pointer outlives the stack frame, scary unexpected data corruption is par for the course. Do not allow that to happen.
When will the pointer be used?
Anything in or called by the stack frame in which the memory is first used is OK. Anything above that, and the memory is not yours to play with. Make sure that you never ever EVER EVER EVER return a pointer to stack memory you've just got.
To reiterate:
Do:
#include <stdio.h>
int main(int argc, char *argv[]) {
int nums = {12, 630, 43, 0};
printf("%d", sum(nums));
}
int sum(int *num_pointer) {
int count = 0;
for (; *num_pointer; num_pointer += 1) {
add(&count, *num_pointer);
}
return count;
}
void add(int *a, int b) {
*a += b;
}
Don't:
int main(int argc, char *argv[]) {
print_int(get_int(7));
}
int *get_int(int value) {
return &value;
}
void print_int(int *num) {
printf("%d", *num);
}
Also, don't type-cast when you don't have to. It's a big sign pointing towards bad program design; consider revising it.

Function Returning Itself

Is it possible to declare some function type func_t which returns that type, func_t?
In other words, is it possible for a function to return itself?
// func_t is declared as some sort of function pointer
func_t foo(void *arg)
{
return &foo;
}
Or would I have to use void * and typecasting?
No, you cannot declare recursive function types in C. Except inside a structure (or an union), it's not possible to declare a recursive type in C.
Now for the void * solution, void * is only guaranteed to hold pointers to objects and not pointers to functions. Being able to convert function pointers and void * is available only as an extension.
A possible solution with structs:
struct func_wrap
{
struct func_wrap (*func)(void);
};
struct func_wrap func_test(void)
{
struct func_wrap self;
self.func = func_test;
return self;
}
Compiling with gcc -Wall gave no warnings, but I'm not sure if this is 100% portable.
You can't cast function pointers to void* (they can be different sizes), but that's not a problem since we can cast to another function pointer type and cast it back to get the original value.
typedef void (*fun2)();
typedef fun2 (*fun1)();
fun2 rec_fun()
{
puts("Called a function");
return (fun2)rec_fun;
}
// later in code...
fun1 fp = (fun1)((fun1)rec_fun())();
fp();
Output:
Called a function
Called a function
Called a function
In other words, is it possible for a function to return itself?
It depends on what you mean by "itself"; if you mean a pointer to itself then the answer is yes! While it is not possible for a function to return its type a function can return a pointer to itself and this pointer can then be converted to the appropriate type before calling.
The details are explained in the question comp.lang.c faq: Function that can return a pointer to a function of the same type.
Check my answer for details.
Assume the function definition
T f(void)
{
return &f;
}
f() returns a value of type T, but the type of the expression &f is "pointer to function returning T". It doesn't matter what T is, the expression &f will always be of a different, incompatible type T (*)(void). Even if T is a pointer-to-function type such as Q (*)(void), the expression &f will wind up being "pointer-to-function-returning-pointer-to-function", or Q (*(*)(void))(void).
If T is an integral type that's large enough to hold a function pointer value and conversion from T (*)(void) to T and back to T (*)(void) is meaningful on your platform, you might be able to get away with something like
T f(void)
{
return (T) &f;
}
but I can think of at least a couple of situations where that won't work at all. And honestly, its utility would be extremely limited compared to using something like a lookup table.
C just wasn't designed to treat functions like any other data item, and pointers to functions aren't interchangeable with pointers to object types.
what about something like this:
typedef void* (*takesDoubleReturnsVoidPtr)(double);
void* functionB(double d)
{
printf("here is a function %f",d);
return NULL;
}
takesDoubleReturnsVoidPtr functionA()
{
return functionB;
}
int main(int argc, const char * argv[])
{
takesDoubleReturnsVoidPtr func = functionA();
func(56.7);
return 0;
}
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
typedef void *(*fptr)(int *);
void *start (int *);
void *stop (int *);
void *start (int *a) {
printf("%s\n", __func__);
return stop(a);
}
void *stop (int *a) {
printf("%s\n", __func__);
return start(a);
}
int main (void) {
int a = 10;
fptr f = start;
f(&a);
return 0;
}
It is not possible for a function to return itself by value. However it is possible itself to return by a pointer.
C allows to define function types that take undefined number of parameters and those those types are compatible with function types that take defined parameters.
For example:
typedef void fun_t();
void foo(int);
fun_t *fun = foo; // types are fine
Therefore the following function would work.
void fun(void (**ptr)()) {
*ptr = &fun;
}
And below you can find the exemplary usage:
#include <stdio.h>
void fun(void (**ptr)()) {
puts("fun() called");
*ptr = &fun;
}
int main() {
void (*fp)();
fun(&fp); /* call fun directly */
fp(&fp); /* call fun indirectly */
return 0;
}
The code compiles in pedantic mode with no warnings for C89 standard.
It produces the expected output:
fun() called
fun() called
There's a way, you just try this:
typedef void *(*FuncPtr)();
void *f() { return f; }
int main() {
FuncPtr f1 = f();
FuncPtr f2 = f1();
FuncPtr f3 = f2();
return 0;
}
If you were using C++, you could create a State object type (presuming the state machine example usage) wherein you declare an operator() that returns a State object type by reference or pointer. You can then define each state as a derived class of State that returns each appropriate other derived types from its implementation of operator().

Can you printf value from a void * in C

Ok, I'm trying to do this, but it isn't working becuase I'm not dereferencing the pointer... is there a way to do it without making a switch statement for the type?
typedef struct
{
char *ascii_fmtstr;
int len;
int (*deserializer)(void *in, const char *ascii);
int (*serializer)(const void *in, char *ascii);
} FORMAT;
const FORMAT formats[]=
{
{"%d\n", 2/2} //Int
,{"%s\n", STRSIZE/2} //String
,{"%.4f\n", 4/2} //Float
,{"%lld", 4/2} //Long-Long
,{"%s\n", STRSIZE/2} //Time
};
typedef struct {
int fmtindex;
void * vp;
} JUNK;
float f = 5.0f;
int i=1;
char foo[]="bar";
JUNK j[] = {
{2, &f}
,{0, &i}
,{1, foo}};
void dump(void)
{
int i;
for(i=0;i<2;i++)
printf(formats[j[i].fmtindex].ascii_fmtstr, j[i].vp);
}
It seems like you're using void * as a cheap union. That's a pretty bad idea. I think you'll find unions in conjunction with enums and switches make this look so much neater, in C. You'll find the switch amongst the #ifdef SWITCH ... #else, and the switchless version amongst the #else ... #endif.
#include <stdio.h>
struct object {
enum type {
d=0,
s=1,
f=2,
lld=3,
time=4
} type;
union instance {
int d;
char *s;
float f;
long long lld;
char *time;
} instance;
};
#ifdef SWITCH
void print_object(struct object *o) {
switch (o->type) {
case d: printf("%d", o->instance.d); break;
case s: printf("%s", o->instance.s); break;
case f: printf("%f", o->instance.f); break;
case lld: printf("%lld", o->instance.lld); break;
case time: printf("%s", o->instance.time); break;
};
}
#else
void print_d(struct object *o);
void print_s(struct object *o);
void print_f(struct object *o);
void print_lld(struct object *o);
void print_time(struct object *o);
void print_object(struct object *o) {
void (*print_functions[])(struct object *) = {
[d] = print_d,
[s] = print_s,
[f] = print_f,
[lld] = print_lld,
[time] = print_time
};
print_functions[o->type](o);
}
void print_d(struct object *o) { printf("%d", o->instance.d); }
void print_s(struct object *o) { printf("%s", o->instance.s); }
void print_f(struct object *o) { printf("%f", o->instance.f); }
void print_lld(struct object *o) { printf("%lld", o->instance.lld); }
void print_time(struct object *o) { printf("%s", o->instance.time); }
#endif
int main(void) {
struct object o = { .type = d, /* type: int */
.instance = { .d = 42 } /* value: 42 */ };
print_object(&o);
return 0;
}
You can print the pointer itself with something like %p but, if you want to print what it points to, you need to tell it what it is:
printf ("%d", *((int*)myVoidPtr));
You're not allowed to dereference a void * simply because the compiler doesn't know what it points to.
Think about it this way : Any pointer simply points to a single memory location.But the type of the pointer determines how many bytes after that to interpret/consider.If it is char* then (depending on system) 1 byte is interpreted,if it is an int* 4 bytes are interpreted, and so on.But a void* had no type.So you can't dereference a void pointer in C due to this simple reason.But you can print out the address it points to using the %p format specifier in printf() and passing that void pointer as argument.
printf("The address pointed by void pointer is %p",void_ptr); //Correct
printf("The address pointed by void pointer is %p",(void*)int_ptr);//Correct
assuming int_ptr is an integer pointer,say,and void_ptr is a void pointer.
printf("Value at address pointed by void pointer is %d",*void_ptr);// Wrong
printf("Value at address pointed by void pointer is %d",*(void*)int_ptr);//Wrong
It is not clear what your real goal is. Yes, there are ways to print data type dependent. Basically the idea is to create your own print function.
But only supplying the pointer will not be enough. In any case you need to supply pointer and the type of it.
Lets assume we have a function myprint:
myprint("%m %m %m %i", TYPE_INT, &i, TYPE_FLOAT, &f, TYPE_STRING, foo, 10);
would be a possible call. myprint is a varargs function then which needs to reconstruct the format string and arguments and then can call real printf.
If you use heap variables only, the type of the variable can be stored together with the data with some tricks (hint: check how malloc stores the block size). This would make the additional arguments superflous.
There are other solutions to that, but a good suggestion is not possible without knowledge of your real goal and the exact conditions.
I think the printf and its friends (fprintf, etc.) can dereference only char* which will be interpreted as a c-string.
Actually you can write such function yourself, because you will tell your function how to dereference void* with format flags.
Also you can add to the formats as a third value a pointer to required dereference function that will take as argument a void* and will return the value instead of pointer.
So you will need to write a function for each of the types you use in your formats and assign each function to each format properly.

passing functions as arguments in C [duplicate]

This question already has answers here:
Use of function pointer in C
(5 answers)
Closed 8 years ago.
I'm looking through one of my textbooks, and I see the following line of code for a C function:
node_t* func(node_t* n, int f(node_t *))
What exactly does this mean? There is a function as an argument in there. What is the point of that? Shouldn't you just be able to call any function in the file as long as it's been declared?
Also, in terms of assembly, is it the memory location of int f() that is being referenced?
Thank you.
node_t* func(node_t* n, int f(node_t *))
Is a function, called func that takes two parameters: n, a pointer to a node_t, and f, a pointer to a function that takes a node_t pointer and returns an int. The function func returns a pointer to a node_t.
Anyway, the most common use of this that comes to mind is for generic algorithms.
"Shouldn't you just be able to call any function in the file as long as it's been declared?"
As long as the function has been declared in the compilation unit, and the linker can find it at link time, that is true. However, function pointers are used when you want to be able to decide at run time which function to use (or compile time if you just want a generic function).
As a tangible example, consider qsort:
void qsort ( void * base, size_t num, size_t size, int ( * comparator ) ( const void *, const void * ) );
Now consider this:
typedef struct Student { int id; char* name; }
Student students[10];
//populate students
int sortByName(void* a, void* b)
{
Student* sa = a;
Student* sb = b;
return strcmp(a->name, b->name);
}
int sortById(void* a, void* b)
{
Student* sa = a;
Student* sb = b;
return a->id - b->id;
}
//sort by name:
qsort(students, 10, sizeof(Student), sortByName);
//sort by id:
qsort(students, 10, sizeof(Student), sortById);
The important part is that the sorting code didn't have to be changed. The sorting implementation is effectively generic. It's one algorithm that operates on different data types, and in this case, this generic-ness is facilitated by a function pointer.
There's other uses of function pointers as well (quite a few of them), such as call backs, or branching based on a map that maps something to a function.
The second argument is a function pointer to a function with signature int(node_t *). This way you can pass a call-back to func, like this:
int foo(node_t * p) { /* ... */ }
node_t n;
func(&n, foo); // note: the second argument is the function pointer
Here's a very stupid example to use this to move around a fictitious array:
T * array_next(T * arr, int n) { return arr + n; }
T * array_prev(T * arr, int n) { return arr - n; }
T * move_in_array(T * arr, T * (*f)(T *, int))
{
return f(arr, 1);
}
Now you can write code that moves around in an array in a run-time determined fashion using the callbacks:
T * p = move_in_array(some_array, flag ? array_next : array_prev);
The key design idea here is that we have a generic action function move_in_array whose specific implementation is passed as an argument in form of a function pointer.

Getting error when modifying MyType constructed using typedef in C

I create a type and try to change the int value in it.
But it keeps printing 240.
I don't know why, can anyone help me?
Here is my code:
typedef struct{
int i;
}MyType;
do(MyType mt, int ii){
mt.i = ii;
}
int main(int argc, char ** argv){
MyType mt;
do(mt, 5);
print("%d\n", mt.i);
}
Passing mt by value to function do(). Any changes made will be local to the function. Pass the address of mt:
void do_func(MtType* mt, int ii){
mt->i = ii;
}
MyType mt;
do_func(&mt, 5);
So first, your do function has some problems. You have failed to specify a return type, so int is assumed (pre-C99), but I see no reason to not just specify it. Second, do is a reserved keyword in C.
You are passing your struct by value, so a copy is made, passed to your do function, and that is modified. Everything is passed by value in C, period. Your mt variable declared in main is never touched.
Take a MyType* in your code if you need to modify one or more of its member variables, take a MyType** if you need to allocate memory for the structure itself (i.e., initialize a pointer).
// pass a pointer to the function to allow
// for changes to the member variables to be
// visible to callers of your code.
void init_mytype(MyType *mt, int ii){
if(mt)
mt->i = ii;
}
MyType mt;
init_mytype(&mt, 1);
// pass a pointer to pointer to initialize memory
// for the structure and return a valid pointer.
// remember, everything is passed by value (copy)
void init_mytype(MyType **mt, int ii) {
if(mt) {
*mt = malloc(sizeof(MyType));
if(*mt)
(*mt)->i = ii;
}
}
MyType *pmt;
init_mytype(&pmt, 1);

Resources