Matt
Matt

Reputation: 482

C functions as parameters?

So I took a part of a code for my problem from an example but it's not working how I was expecting it.First module it's the place where I first try to use the function,second it's the definition of the function,in the 3rd module are the functions in the header(the corresponding code is at it's place)and the 4th module is some explanation I found of those functions.Can anyone help me undestand what's wrong?

First module problem: Multiple markers at this line

repo->TList = create(cmpTrans, cpyT, delT);

Second module

Vector* create(CmpFun cmp, CpyFun cpy, DelFun del)
{
    Vector* v = (Vector*)malloc(sizeof(Vector));
    v->len = 0;
    v->capacity = 10;
    v->elems = (TElem)malloc(10*sizeof(TElem));
    v->cmp = cmp;
    v->del = del;
    v->cpy = cpy;
    return v;
}

Third module

transaction* cpyT(transaction* t);
void delT(transaction* t);
int cmpTrans(transaction* s1, transaction* s2);
    /*
     * Creates a copy of a transaction
     * Input: t - pointer to transaction
     * Output:  t' - a copy of transaction t
     *          t'->day = t->day; s'->type = t->type; t'->desc = t->desc; t'->amount = t->amount;
     *          * Deallocates the memory pointed to by the given instance
     * Deallocates the memory pointed to by the given instance
     * Input: t - pointer to transaction
     * Output: memory pointed to by t is deallocated
     * Input: s1, s2 - pointers to transaction
     * Output:  1 - if all the attributes of the 2 transactions coincide
     *          0 - otherwise
     */

Module four:

 typedef void* TElem;
/*
 * Pointer to a comparison function for two generic elements
 */
typedef int (*CmpFun)(TElem, TElem);

/*
 * Pointer to a function that clones (copies) a generic element
 */
typedef TElem (*CpyFun)(TElem);

/*
 * Pointer to a function that deletes (deallocates) a generic element
 */
typedef void (*DelFun)(TElem);

Upvotes: 1

Views: 126

Answers (1)

Carl Norum
Carl Norum

Reputation: 224864

Your function pointer typedefs all take/return TElem types, which means void *. You're declaring functions that take/return transaction * types. That makes the function pointers you make from those functions incompatible with the typedefs you created:

      transaction *(*)(transaction *) != TElem (*)(TElem)
int (*)(transaction *, transaction *) != int (*)(TElem, TElem)
              void (*)(transaction *) != void (*)(TElem)

You may be getting confused because in C, conversions between void * and other pointer types are implicit. However, conversions between function pointer types, one of which takes void * parameters and one that doesn't, are not.

To fix it, you need to rewrite cpyT, delT, and cmpTrans to use the matching signatures:

TElem cpyT(TElem t);
void delT(TElem t);
int cmpTrans(TElem s1, TElem s2);

Alternatively you can force things through by typecasting when you call create:

repo->TList = create((CmpFun)cmpTrans, (CpyFun)cpyT, (DelFun)delT);

Upvotes: 1

Related Questions