1

I have a function which expects parameters like this

void priqueue_init(priqueue_t *q, int(*comparer)(void *, void *))

I want it to be able to take arguments of any type.

In a separate file I first typedef

typedef int (*comp_funct)(job_t*, job_t*);

And the function I want to pass...

int fcfs_funct1(job_t* a, job_t* b)
{
  int temp1 = a->arrival_time;
  int temp2 = b->arrival_time;

  return (temp1 - temp2);
}

The call to priqueue_init:

priqueue_init(pri_q, choose_comparator(sched_scheme));

And finally, my choose_comparator function:

comp_funct choose_comparator(scheme_t scheme)
{
    if (sched_scheme == FCFS)
        return fcfs_funct1;

    return NULL;
}

I error on my call to priqueue_init.

    libscheduler/libscheduler.c: In function ‘add_to_priq’:
libscheduler/libscheduler.c:125:3: error: passing argument 2 of ‘priqueue_init’ from incompatible pointer type [-Werror]
In file included from libscheduler/libscheduler.c:5:0:
libscheduler/../libpriqueue/libpriqueue.h:25:8: note: expected ‘int (*)(void *, void *)’ but argument is of type ‘comp_funct’

Where am I getting hung up? The file where priqueue_init is defined doesn't know about the type job_t. I thought going with void arguments was the way to go.

0

2 Answers 2

3

int (*comparer)(void *, void *) and int (*comp_funct)(job_t*, job_t*) aren't compatible types. Change them to match, or add a typecast.

Pointers (void * and job_t * in your case) don't have to be the same size, so the compiler is rightly giving you an error. Since they are the same size on most machines, a simple typecast might solve your problem, but you'd be introducing some potential nonportability.

Sign up to request clarification or add additional context in comments.

2 Comments

I didn't actually know this, but it's verified in this answer to Are all data pointers of the same size in one platform?. How can memcpy and friends possibly be guaranteed to work then?
@detly, conversions to and from void * are well defined. The calling conventions needn't make them compatible, though, which is why the function pointer in OP's question has a problem.
2

To be compatible with the function type signature, your comparison functions must take void* parameters, and cast them internally:

int fcfs_funct1(void* a, void* b)
{
  int temp1 = ((job_t*)a)->arrival_time;
  int temp2 = ((job_t*)b)->arrival_time;

  return (temp1 - temp2);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.