2

I have a function that takes a function pointer and apply it over a list. It's prototype is as follows:

void applyList(List *, void applyFunc(void *));

Now I want to supply a function that prints the element in the list. Since I'm not modifying the list element, the print function looks like this:

void printNode(const void *nodeData){
    Data *dPtr=(Data*)nodeData;
    printf("%s", dPtr->str );
}

//Usage
applyList(list, printNode);

However I got an compiler error saying

expected ‘void (*)(void *)’ but argument is of type ‘void (*)(const void *)’

I don't want to add const to apply's prototype, because I might supply some function that modifies the data. Any suggestion on how to deal with this situation?

Wei Shi
  • 4,945
  • 8
  • 49
  • 73

2 Answers2

3

Unfortunately, in C function pointers are not polymorphic. At all. Attempting to force a cast leads to undefined behavior.

Your only standard-conforming way out is to write a wrapper function:

static void wrap_printNode(void *nodeData) {
  printNode(nodeData);
}

Note, however, that your const is kind of useless here:

Data *dPtr=(Data*)nodeData;

You just casted away the const declaration. Try to keep it on there:

const Data *dPtr=(const Data*)nodeData;
bdonlan
  • 224,562
  • 31
  • 268
  • 324
  • Technically there is a very small and verbose degree of polymorphism (http://stackoverflow.com/a/559671/163349), but you are correct that not even `((void(*)(void*))void_from_void_const_ptr)(p)` is defined. – David X Dec 20 '14 at 21:08
0

I don't want to add const to apply's prototype, because I might supply some function that modifies the data.

Then there is no sane solution. The data isn't yours to modify, which is why it's marked const.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358