0

In brief, I am attempting to use a void pointer as a parameter to a function pointer, but am getting the compiler error "invalid use of void expression".

I have a doubly linked list (DLL) whose node structure is as follows:

typedef struct DL_LIST
{
    uint16 tag;                 /* Object ID tag */
    struct DL_LIST *previous;
    struct DL_LIST *next;
    void *object;               /* A pointer to this node's object */
    uint32 size;                /* The size of this node's object, in bytes */
} DL_LIST;

I also have the following function which is used to delete a single such node:

void dl_delete(DL_LIST *node, void (*dl_destructor)(void*)) {
    if (node != NULL) {
        dl_extract(node);       /* Removes the node from the list */

        if (node->object != NULL) {
            (*dl_destructor)(node->object);

            free(node->object);
        }

        free(node);
    }
}

where the node extraction function is:

DL_LIST *dl_extract(DL_LIST *node) {
    if (node != NULL) {
        if (node->previous != NULL) {
            node->previous->next = node->next;
        }

        if (node->next != NULL) {
            node->next->previous = node->previous;
        }

        node->previous = NULL;
        node->next = NULL;
    }

    return node;
}

The idea here is to be able to pass a separate destructor function for each type of object that may be stored in a node. This destructor function takes a pointer to the object as a parameter, and is used to free any heap memory that is being used by children of the object.

The aforementioned error occurs when I try to call dl_delete() from a function designed to delete an entire DLL:

void dl_destroy(DL_LIST **list, void (*dl_destructor)(void*)) {
    DL_LIST *marker;
    DL_LIST *previous_node;

    if (*list != NULL) {
        previous_node = (*list)->previous;

        while (previous_node != NULL) {
            marker = previous_node->previous;
            dl_delete(previous_node, (*dl_destructor)(previous_node->object));
            previous_node = marker;
        }

        /* Code removed for brevity */
    }
}

I have read this introduction to function pointers, but am still unable to determine how to remedy the problem. An explanation of what I am doing wrong would be most appreciated.

Community
  • 1
  • 1
RBE
  • 175
  • 1
  • 11
  • For completeness you might want to include your `dl_extract(node)` function in the question. – Floris Feb 13 '13 at 03:13

1 Answers1

3

this line

dl_delete(previous_node, (*dl_destructor)(previous_node->object));

needs to be dl_delete(previous_node, dl_destructor);

also in dl_delete this line (*dl_destructor)(node->object);

should be dl_destructor(node->object);

also, just for safety, I like to check that my function pointers are not null before trying to make a call using them

so in dl_delete something like :-

if(dl_destructor!=NULL) dl_destructor(node->object);
Keith Nicholas
  • 43,549
  • 15
  • 93
  • 156
  • In your first recommended change Keith, why did you drop the object argument from the `dl_destructor` function? How does the function work without it? – RBE Feb 13 '13 at 03:24
  • because you are wanting to pass a pointer to a function..... what you are seemingly trying to do is call the function. Once you declare a function pointer. It acts as a normal pointer. When you want to call the function it points to, you just call the pointer as if its a function – Keith Nicholas Feb 13 '13 at 03:30
  • hard to explain, but the only time you use the funny function pointer syntax is when declaring it. (quite often people typedef it) – Keith Nicholas Feb 13 '13 at 03:32