Error Invalid use of void expression - c

I have a function int rt_task_start (RT_TASK *task, void(*task_func)(void *arg), void *arg)
where in second argument i am passing a function with argument.
When i only pass a function name at that time there is no problem.(as expected it's working). rt_task_start(&demo_task1, demo, 1);
But when i pass rt_task_start(&demo_task1, demo(&val), 1); it's giving me error error: invalid use of void expression. Variable val is defined before. int val = 0;
When i call with this rt_task_start(&demo_task1, demo(val), 1); this is showing error Warning passing argument 1 of 'demo' makes pointer from integer without a cast then error: invalid use of void expression.
int *val;
*val = 0;
rt_task_start(&demo_task1, demo(&val), 1); this is also giving me error.
I can't understand what should i pass, as a void pointer. It's giving me error. Any Idea Please!

void (*task_func)(void *arg);
The above statement defines task_func to be a pointer to a function which takes a pointer of type void * and returns no value.
Therefore, when you call your function rt_task_start, you should pass a pointer to a function as the second argument. Also, you should pass a pointer of type void * as the third argument, not an integer. A function name evaluates to a pointer to the function, so you can simply pass the function name as the argument value, or you can use the address-of operator & before the function name.
int arg = 4;
// both calls are equivalent
rt_task_start(&demo_task1, demo, &arg);
rt_task_start(&demo_task1, &demo, &arg);

I'm not sure how the code in (1) can possibly compile. But here is what you should be using:
int rt_task_start (RT_TASK *task, void(*task_func)(void *arg), void *arg);
int val = 1;
rt_task_start(&demo_task1, demo, &val);
You cannot pass the function pointer bound to a specific argument, that is something like a closure, which isn't available in C. You can, however, pass the function pointer and then separately pass the argument you want to apply (which is what the function signature suggests you should do). But you must pass that argument as a pointer, not a literal.

Surely you want:
int i=1;
rt_task_start(&demo_task1, demo, (void*) &i);
Just by matching the argument types, remember the second argument is just a function pointer, not a function call with its own argument, it's own argument is only used when you call it within rt_task_demo. If you then want to use the value '1' in function 'rt_task_demo' you would recast it like
int ii = *(int*) arg;

Related

Meaning of returns char when return value is void, and gets an void argument?

I am learning about threading with C, and I'm a bit confused about the example given. They declared a function print_name with return value of void, but then it returns a string — how and why? The function print_name accepts one argument which is called name but it is a pointer of void; what does a variable of type void mean, and how can it accept a string?
main.c
#include <stdio.h> // I-O
#include <pthread.h> // threading
void *print_name(void *name)
{
puts(name);
return name;
}
int main(int argc, char const *argv[])
{
pthread_t thread_id;
pthread_create(&thread_id, NULL, print_name, "ha ones be eilat");
pthread_join(thread_id, NULL);
return 0;
}
To compile and run with gcc
$ cc main.c -o main -Wall -pthread && ./main
ha ones be eilat
The argument type and return type is not void but pointer to void.
In C both argument passing and returning a value with the return statement happen as if by assignment. void * is a generic pointer type and conversions to and from void * from and to other pointer types will happen implicitly, i.e. without a cast.
The character literal which is an array of char decays to char * and is implicitly converted to void * to match the prototype of pthread_create. The void * is implicitly converted to char * to match the prototype of puts.
print_name has prototype void * print_name(void *) so that a pointer to that function will match the type expected by pthread_create (The third parameter is void *(*start_routine) (void *).)
The declaration of pthread_create is
int pthread_create(
pthread_t *thread,
const pthread_attr_t *attr,
void *(*start_routine) (void *),
void *arg
);
The type void * is a 'universal pointer' that can point to any object type. (On many, but not all, machines, a void * can also hold a function pointer — however, that's tangential to this question.) In C, any object pointer can be converted to a void * and back to the original type without change. Using void * can be dangerous; it can be extremely useful (and thread creation can show both dangerousness and usefulness).
Contrary to the claim in the question, the function print_name() is defined to return a void * value as well as accept a void * argument. The pthread_create() function expects a (pointer to a) thread function that matches the signature:
void *thread_function(void *);
And that's what is passed to it. Since the function returns a void *, it is legitimate to return the pointer it was passed, though that is actually an unusual thing to do.
The return value from the thread function can be collected by passing an appropriate, non-NULL pointer to pthread_join(); the example does not demonstrate that.
void *result;
if (pthread_join(thread_id, &result) == 0)
printf("Result: <<%s>>\n", result);
This would, in the example, print Result: <<ha ones be eilat>> on a line. Many times, you'd convert the returned pointer to an explicit non-void pointer — e.g. char *str = result; — and then use that.
Note that there is nothing in C that would stop you calling:
int i = 0;
if (pthread_create(&thread_id, NULL, print_name, &i) != 0)
…thread creation failed…
The wrong type of data is passed, but that will be treated as OK by the compiler. At run-time, if you're (un)lucky, an empty line will be printed, but anything is possible (because of undefined behaviour) as you passed an int * to a function that requires a char * to work correctly. This inability to check types is a weakness of void *, but it is also a strength as it allows the pthread_create() function to pass a pointer to any type of data to a function. The onus is on the programmer to get the types right — the called function must expect to convert the void * parameter to a pointer to the type that was really passed. Also, the data passed via the pointer to the function needs to be stable — not changed if another thread is started. There is no guarantee about the order in which threads will read the data passed. Passing a pointer to a structure and changing the value in the structure between calls to pthread_create() is a no-no. Similarly with the return value. There are some additional wrinkles there. The data pointed at must be valid after the function exits, so it can't be a local variable.

pthread/uthread type variable

In studying uthreads (from pthreads), I have come across the following line of code:
uthread_t uthread_create (void* (*start_proc)(void*), void* start_arg)
I am not sure what uthread_create() is taking as the first parameter. Is it taking pointer to no specific type casted to pointer to type start_proc? Can someone clarify?
The first argument is a function pointer. start_proc points to a function that takes a single void * parameter and returns a void *, which in this case is the entry point for a thread. Also, the second argument to uthread_create is the parameter which will get passed to start_proc when it is called.
A function like this would satisfy the function pointer:
void *my_thread(void *p)
{
char *s = p;
printf("s=%s", s);
return NULL;
}
And you could call uthread_create like this:
uthread_t tid;
char str[] = "test string";
tid = uthread_create(my_thread, str);

Threads creation in C

void print_hello_world() {
pid_t pid = getpid();
printf("Hello world %d\n", pid);
pthread_exit(0);
}
void main() {
pthread_t thread;
pthread_create(&thread, NULL, (void *) &print_hello_world, NULL);
print_hello_world();
}
I really couldn't understand what is the need of (void *) in pthread_create. And do we need "&print_hello_world" in the same or could drop "&" as I have read somewhere that while passing function pointers we don't need to place "&" before the function name.
Yes, there's no need for cast or & operator there:
pthread_create(&thread, NULL, print_hello_world, NULL);
should suffice as a function name gets converted into a function pointer when passing as argument to function(s).
Note that the function pointer you pass to pthread_create() takes a void* as argument and returns a void *. So your function should be:
void* print_hello_world(void *unused) {
...
}
It's the C way of implementing "generic" data type. For example, you can pass a int* or struct args* to the thread function and retrieve it back.
E.g.
int i=5;
pthread_create(&thread, NULL, print_hello_world, &i);
and in the function print_hello_world(), you would do:
void *print_hello_world(void *value) {
int i = *(int*)value;
...
}
Basically void* allows you to pass any data pointer to the thread function here. If pthread_create()'s thread function were to take int*, you wouldn't be able to pass a struct args* to it, for example.
I suggest you read the following posts for more information on void pointer and its usage in C:
Concept of void pointer in C programming
and
What does void* mean and how to use it?
Casting a function pointer to/from void * is actually undefined behaviour. See 6.3.2.3, especially p1 and p8. Note that functions are no objects in C.
So the cast is wrong in fact and the addressof-operator & is unnecessary. You can cast, however, one function pointer to another (see §8 of the reference). But here, you shoud definitively have a proper signature for your function, as there is a reason it takes a pointer and returns one, too. So: do not cast, but get the signature (and semantics) correct.
Note: An empty identifier-list in a function declaration which is part of the definition is an obsolescent feature. Using the prototype-style (void) for an empty argument list is recommended. Also the minimal required signature for main is int main(void) (with respect to the above said).

interaction with hardware in c

calling a function by a pointer which hold the address of the function is generating error
code:
p=GetProcAddress(h,"installhook");//p is a pointer that holds the address returned from getprocaddress() function
(*p)(); //using this pointer making a call to installhook function
but the code is generating error wher i am making a call by (*p)(); it says term does not evaluate to a function.
how doi overcome with this?is there any other way making a call to the function using pointer?
You need to cast the return value of GetProcAddress to the correct function type. For example:
typedef void (*FuncPtr)(); //assuming a function like void f()
FuncPtr p;
p = (FuncPtr) GetProcAddress(h, "funcName");
if (p)
p();
else
printf("Function not found\n");
Verify p is declared like this:
void (*p)(void);
and that the type of the return value of GetProcAddress is the same.

Problem with the following code

I want to the know the problems with the code presented below. I seem to be getting a segmentation fault.
void mallocfn(void *mem, int size)
{
mem = malloc(size);
}
int main()
{
int *ptr = NULL;
mallocfn(ptr, sizeof(ptr));
*ptr = 3;
return;
}
Assuming that your wrapper around malloc is misnamed in your example (you use AllocateMemory in the main(...) function) - so I'm taking it that the function you've called malloc is actually AllocateMemory, you're passing in a pointer by value, setting this parameter value to be the result of malloc, but when the function returns the pointer that was passed in will not have changed.
int *ptr = NULL;
AllocateMemory(ptr, sizeof(ptr));
*ptr = 3; // ptr is still NULL here. AllocateMemory can't have changed it.
should be something like:
void mallocfn(void **mem, int size)
void mallocfn(int **mem, int size)
{
*mem = malloc(size);
}
int main()
{
int *ptr = NULL;
mallocfn(&ptr, sizeof(ptr));
*ptr = 3;
return;
}
Because you need to edit the contents of p and not something pointed b p, so you need to send the pointer variable p's address to the allocating function.
Also check #Will A 's answer
Keeping your example, a proper use of malloc would look more like this:
#include <stdlib.h>
int main()
{
int *ptr = NULL;
ptr = malloc(sizeof(int));
if (ptr != NULL)
{
*ptr = 3;
free(ptr);
}
return 0;
}
If you're learning C I suggest you get more self-motivated to read error messages and come to this conclusion yourself. Let's parse them:
prog.c:1: warning: conflicting types for built-in function ‘malloc’
malloc is a standard function, and I guess gcc already knows how it's declared, treating it as a "built-in". Typically when using standard library functions you want to #include the right header. You can figure out which header based on documentation (man malloc).
In C++ you can declare functions that have the same name as already existing functions, with different parameters. C will not let you do this, and so the compiler complains.
prog.c:3: warning: passing argument 1 of ‘malloc’ makes pointer from integer without a cast
prog.c:3: error: too few arguments to function ‘malloc’
Your malloc is calling itself. You said that the first parameter was void* and that it had two parameters. Now you are calling it with an integer.
prog.c:8: error: ‘NULL’ undeclared (first use in this function)
NULL is declared in standard headers, and you did not #include them.
prog.c:9: warning: implicit declaration of function ‘AllocateMemory’
You just called a function AllocateMemory, without telling the compiler what it's supposed to look like. (Or providing an implementation, which will create a linker error.)
prog.c:12: warning: ‘return’ with no value, in function returning non-void
You said that main would return int (as it should), however you just said return; without a value.
Abandon this whole idiom. There is no way to do it in C without making a separate allocation function for each type of object you might want to allocate. Instead use malloc the way it was intended to be used - with the pointer being returned to you in the return value. This way it automatically gets converted from void * to the right pointer type on assignment.

Resources