makecontext function pointer [error: invalid use of void expression] - c

I have the following code (its for an threads library to a class):
int tcb_context_create(TCB *thread, void (*start)(void*), void *arg) {
if (!makecontext( &(thread->context), (void (*) (void)) start, 1, arg)) {
errno = EAGAIN;
return -1;
}
return 0;
}
But i the compiler keep giving 'error: invalid use of void expression' i have searched everywhere and cant find the corrent way to use the makecontext function.
corrected:
int tcb_context_create(TCB *thread, void (*start)(void*), void *arg) {
makecontext( &(thread->context), (void (*) (void)) start, 1, arg);
return 0;
}

The return type of makecontext is void. Using ! on a void is not correct.
In addition, you don't have a return statement outside the if block. Since the function's return type is int, you need to add a proper return statement. Otherwise, you will run into undefined behavior.

Related

Can't get around to how to pass a function as a parameter

I'm trying to pass this function: void* checkMatrix(); as an argument to this function: void createThreads(void*(*f));.
I've read a post here so my decleration above is a result of this.
I'm calling the function like this: createThreads(checkMatrix); but it gives me a warning that type is incompatible [void** and void*()]. I can get around with a fast cast but it won't fix the problem.
Finally I write the function like this (simple initialization):
void createThreads(void* (*f)) {
pthread_t* a;
int i;
a = (pthread_t*) malloc(*arr.l * sizeof(pthread_t));
if (a == NULL) {
fprintf(stderr, "ERROR!\n");
exit(1);
}
for (i = 0; i < *arr.l; i++) {
if (pthread_create((a + i), NULL, (void*) &f, NULL)) {
fprintf(stderr, "ERROR IN THREAD CREATION!\n");
exit(2);
}
}
for (i = 0; i < *arr.l; i++)
pthread_join(*(a + i), NULL);
}
In conclusion, the problem is that it stops, with memory problem, but the cause is the creation of the threads and espacially in the 3rd argument that I specify the function that the thread will work on. I think I'm doing something wrong with the calling. I can't find the answer and can't get around it.
Thanks for your time!
void* (*f) is just void **f with a set of redundant parentheses. You probably wanted to use this for the parameter type:
void* (*f)()
However, that is not what pthread_create expects. The thread's main function is supposed to return void* and take a void* parameter. So what you really want is probably this:
void createThreads(void* (*f)(void*)) {
/* ... as before ... */
if (pthread_create((a + i), NULL, f, NULL)) {
/* ... as before ... */
}
To begin with void* checkMatrix(); is obsolete style and shouldn't be used. Second, pthread callback functions take void* as parameter. So use void* checkMatrix(void*); instead.
To pass it to a function, simply do
void createThreads (void* (*f)(void*))
Recommended practice when using function pointers is otherwise to use typedefs, to increase readability. For example you could cook up something like
typedef void* pthread_callback (void*);
void createThreads (pthread_callback* f)
Try changing the function signature to void createThreads(void* (*f)(void *))
and change the pthread_create function call topthread_create((a + i), NULL, f, NULL)

Passing function pointer to arg of pthread_create function

I have a function void startScanner(...) taking two function pointer as arguments: userType *vConfig(void) and void * vCallback(void). In this function i would like to create a thread and call vCallback() function in the function thread created. So i decided to pass vCallback as args to pthreadcreate.
The code of startScanner function :
void startScanner(tUsrStatus (*vConfig)(), void* (vCallback)()){
if(pthread_create(&scannerThread, NULL, scannerThreadFunc, vCallback))
{
printf("Thread creation fails!\n");
}
}
The scannerTread function:
static void *scannerThreadFunc(void *arg()){
void *funcptr(void) = arg;
while(1)
{
funcptr();
}
pthread_exit(NULL);
}
I get the following error:
error: function ‘funcptr’ is initialized like a variable
error: nested function ‘funcptr’ declared but never defined
How can i fix this?
Syntax errors aside (*) , it's impossible in standard C to pass a function pointer in a void *. There's a fundamental difference between pointers to functions and pointers to data, they can't be converted into each other. This is because there might be platforms where function and data pointers would differ even in size, or refer to different address spaces, or whatever.
But of course, there's a simple way to achieve what you want: Put your function pointer inside a struct and pass a pointer to that.
typedef (*callback)(void);
typedef struct threadargs
{
callback cb;
} threadargs;
void mycallback(void)
{
// ...
}
void *threadfunc(void *arg)
{
threadargs *ta = arg;
// call your callback:
ta->cb();
return ta; // or: return 0, or some pthread_exit(), ...
}
int main(void)
{
pthread_t thread;
threadargs ta = { mycallback };
pthread_create(&thread, 0, threadfunc, &ta);
// make sure "ta" lives for as long as the thread executes,
// here just wait until it exits:
pthread_join(&thread, 0);
}
add error checking etc.
(*) as for the concrete error you're getting, a function pointer needs parantheses around the identifier, so instead of
void *funcptr(void) = arg;
you'd have to write
void (*funcptr)(void) = arg;
To facilitate the usage of function pointers, it's common to typedef them, as seen in my example above. Anyways, as explained above, this wouldn't solve your problem here.

C program: pass function as parameter to another function to create thread

I would need some help. I been doing it for hours and is not able to get it to work. Generally, I have a function which access a kernel Driver and I would like to pass that function as a parameter to another function that include some pthread code. I researched and found out that I may need a function pointer.
Here is the function which I want to pass as a parameter.
static void kernelTest(char Send[BUFFER_LENGTH])
{
int fd = open("/dev/kernelTest", O_RDWR);
}
Here is the function which I want to pass in:
static void createKThread(void (*f)(char *))
{
pthread_t t1;
int ret;
ret = pthread_create(&t1, NULL, (*f)(char), NULL);
pthread_join(t1, NULL);
}
I attempted the function pointer but it is giving me error.
error: expected expression before ‘char’
I greatly appreciate any help rendered. Thank You!
(*f)(char) is invalid syntax. It looks like you're attempting to call the function f and passing char as a parameter, which you can't do.
Since you're not actually calling f, just pass it to pthread_create directly:
ret = pthread_create(&t1, NULL, f, NULL);
There's still a problem with this, however. The third parameter to pthread_create is expected to be of type void *(*)(void *), i.e. a pointer to a function that has a void * parameter and returns a void *. Your function has type void (*)(char *), so the parameters are incompatible.
You need to either change the signature of kernelTest to match what pthread_create expects:
static void *kernelTest(void *param)
{
char *send = param;
int fd = open("/dev/kernelTest", O_RDWR);
return NULL;
}
Or you need to create a wrapper function which matches pthread_create:
static void *kernelTest_wrapper(void *param)
{
char *send = param;
kernelTest(send);
return NULL;
}

GCC C compile error, void value not ignored as it ought to be

I'm having trouble compiling some C code.
When I compile, I'l get this error:
player.c: In function ‘login’:
player.c:54:17: error: void value not ignored as it ought to be
This is the code for the error:
static bool login(const char *username, const char *password) {
sp_error err = sp_session_login(g_sess, username, password, remember_me);
printf("Signing in...\n");
if (SP_ERROR_OK != err) {
printf("Could not signin\n");
return 0;
}
return 1;
}
Any way to bypass this kind of error?
Thanks
Edit:
All sp_ functions are from libspotify
Where is the error line exactly?
Without further information, I'm guessing it's here:
sp_error err = sp_session_login(g_sess, username, password, remember_me);
I guess sp_session_login is returning the void.
Try:
static bool login(const char *username, const char *password) {
sp_session_login(g_sess, username, password, remember_me);
printf("Signing in...\n");
return 1;
}
It usually means you assign the return of a void function to something, which is of course an error.
In your case, I guess the sp_session_login function is a void one, hence the error.
I'm going to guess that sp_session_login is declared as returning void and not sp_error and there is some alternative way of determining whether it succeeded.
It doesn't look like sp_session_login actually returns anything. In particular, it doesn't return an sp_error, so there's no way this could work. You can't really bypass it.
You must declare void functions before use them. Try to put them before the main function or before their calls.
There's one more action you can do: You can tell the compiler that you will use void functions.
For exemplo, there are two ways to make the same thing:
#include <stdio.h>
void showMsg(msg){
printf("%s", msg);
}
int main(){
showMsg("Learn c is easy!!!");
return 0;
}
...and the other way:
#include <stdio.h>
void showMsg(msg); //Here, you told the compiller that you will use the void function showMsg.
int main(){
showMsg("Learn c is easy!!!");
return 0;
}
void showMsg(msg){
printf("%s", msg);
}

Implementing callback functions in C

I am a newbie to C. I am trying to implement callback function using function pointers.
I am getting an error
:test_callback.c:10: error: expected identifier or ‘(’ before ‘void’
when I try to compile the following program:
#include<stdio.h>
void (*callback) (void);
void callback_proc ()
{
printf ("Inside callback function\n");
}
void register ((void (*callback) (void)))
{
printf ("Inside registration \n");
callback (); /* Calling an initial callback with function pointer */
}
int main ()
{
callback = callback_proc;/* Assigning function to the function pointer */
register (callback);/* Passing the function pointer */
return 0;
}
What is this error?Can anyone help?
register is a C keyword: Use another name for the function.
You have extra parantheses around the callback parameter. It should be:
void funcName(void (*callback) (void))
I would recommend to use a typedef
#include<stdio.h>
typedef void (*callback_t) (void);
callback_t callback;
void callback_proc(void)
{
printf ("Inside callback function\n");
}
void reg( callback_t _callback )
{
printf ("Inside registration \n");
_callback();
}
int main ()
{
callback = callback_proc;
reg(callback);
return 0;
}
EDIT: removed the register issue
You can't use 'register' as a function name as it's a C keyword.
2 problems:
you can't use the name register as it's a keyword (not used often anymore, but it's still there)
change the definition of the function from
void wasRegister((void (*callback) (void)))
to:
void wasRegister(void (*callback) (void))
(get rid of the parens around the parameter's declaration.
Also you might get a warning about callback_proc() not having a matching delaration to the callback variable (depending on how you compile the program - as C or C++), so you might want to change its declaration to:
void callback_proc (void)
to make it explicit that it takes no parameters.
Have a look at type safe callbacks from ccan. Its one thing to expose a typed function pointer for the world to use, its another to ensure sane casting.
#include<stdio.h>
typedef void (*callback_func) (void);
static callback_func the_callback = 0;
void process (void)
{
printf ("Inside process function\n");
}
void callback_register (callback_func cb)
{
the_callback = cb;
printf ("Inside registration \n");
}
void callback(void)
{
the_callback();
}
int main (void)
{
callback_register(process); /* Passing the function pointer */
callback();
return 0;
}
Declaring the_callback static would make more sense if this code was modularized and then you would be forced to call callback_register in order to set it, and callback in order to call it - the_callback would not be accessible outside of the implementation (.c) only the function declarations would be in the header (.h).

Resources