Search code examples
cgenericscopyfree

can the type returned by a copy function that is given for generic code be any type we want?


I am using a generic adt that has those typedefs:

typedef void *Element;
typedef Element(*copyElements)(Element);
typedef Element(*copyElements)(Element);
typedef void(*freeElements)Element);

and I have to pass them using this create function:

GenericAdt create(copyElements copy,freeElements destroy);

so my questions are: 1)when I write a copy function that I want to pass to this create function can I write it as

SomeOtherType copy( SomeOtherType a);

and not as

Element copy(Element);

???

  1. the same question for the free function can I write it as
void destroy(SomeOtherType a);

and not as

void destroy( Element a);

???


Solution

  • The functions that you pass as parameters to create must be compatible with the types of the parameters.

    For two function types to be compatible, the number and types of the arguments must be the same and the return type must be the same. In your example, SomeOtherType copy( SomeOtherType a) is not compatible with the copyElements type because the return type is different and the parameter type is different. The same applies to void destroy(SomeOtherType a). So you can't pass these to the create function.

    Create these functions with the appropriate type, and cast the relevant pointers inside of the function:

    Element copy(Element e)
    {
        struct SomeOtherType *oldvalue = (struct SomeOtherType *)e;
        
        struct SomeOtherType *newvalue = malloc(sizeof *newvalue ));
        // populate newvalue 
        return (Element)newvalue;
    }
    

    Also regarding this typedef:

    typedef void *Element;
    

    It's generally not a good idea to hide object pointers behind a typedef as it can cause confusion to the reader regarding whether or not a pointer is being used. For function pointers however it's more acceptable as it improves readability.