tags:

views:

63

answers:

2

ueach is a function that loops through a Unicode string, and running the callback on each character by passing a single-character string to it.

string ueach(string s, void *function(string)) {
    unsigned long i;
    for (i = 0; i < s.length; i++)
        function(uchar(s, i));
}

If I have a callback testing:

void testing(string c) {
    puts(utoc(c));
}

which prints the given character (utoc converts Unicode string to a UTF-8 char *) it all works fine. The code used:

string a = ctou("Hello, world!");
ueach(a, &testing);

However, I get this warning:

test.c: In function ‘main’:
test.c:8: warning: passing argument 2 of ‘ueach’ from incompatible pointer type
ulib:171: note: expected ‘void * (*)(struct string)’ but argument is of type ‘void (*)(struct string)’

If I put parentheses around the function part of the ueach prototype like this:

string ueach(string s, void (*function)(string)) { ... }

then it works just fine as well, with no warning.

What is the difference between void * (*)(struct string) and void (*)(struct string)?

What is the difference between void *function(string) and void (*function)(string)?

+3  A: 

It's just a matter of operator precedence. In the error case, the compiler parses it as a function returning a void*, (a pointer to something), rather than a pointer to a function returning void.

Jive Dadson
+4  A: 
  • void * (*)(struct string) - pointer to a function returning a void *.
  • void (*)(struct string) - pointer to function returning void.
  • void *function(string) - function returning a void *
  • void (*function)(string) - pointer to function returning void

The third decays to the first, because:

"except when it is the operand of the sizeof operator or the unary & operator, a function designator with type 'function returning type' is converted to an expression that has type 'pointer to function returning type'."

C99 §6.3.2.1/4

Matthew Flaschen