Take the following C/C++ code:
#include <stdlib.h>
int inc(int i) { return i+1; } // int→int, like abs()
// baz is bool→(int→int)
int (*baz(bool b))(int) { return b ? &abs : &inc; }
int main() {
int (*foo(bool))(int); // foo is &(bool→(int→int))
foo = baz;
}
Attempting to compile this (gcc or g++) gives:
$ g++ test.cc
test.cc: In function ‘int main()’:
test.cc:9: error: assignment of function ‘int (* foo(bool))(int)’
test.cc:9: error: cannot convert ‘int (*(bool))(int)’ to ‘int (*(bool))(int)’ in assignment
Check for yourself: the two types it claims it cannot convert between are exactly the same. Why then is it claiming that they are incompatible?
EDIT 1: The problem disappears when using typedef
s (as is recommended), like so:
int main() {
typedef int (*int2int)(int);
typedef int2int (*bool2_int2int)(bool);
bool2_int2int foo;
foo = baz;
}
EDIT 2: The compiler, of course, was right. The problem with my original code, as many pointed out, is that foo
in main()
is a declaration of a function, and not a function pointer. The error in the assignment was therefore not conflicting types but assigning to a function, which is not possible. The correct code is:
#include <stdlib.h>
int inc(int i) { return i+1; } // int→int, like abs()
// baz is bool→(int→int)
int (*baz(bool b))(int) { return b ? &abs : &inc; }
int main() {
int (*(*foo)(bool))(int); // foo is &(bool→(int→int))
foo = &baz;
}
The code is in fact wrong. The problem is that this line:
int (*foo(bool))(int); // foo is &(bool→(int→int))
... doesn't mean what you think it means. It's interpreted as a declaration of a function named "foo". That makes perfect sense. Think about it - if you had wanted to forward declare "baz", you would have put int (*baz(bool))(int);
, right? Also, since baz is a function which returns a function pointer, and foo is a pointer to a function which returns a function pointer, wouldn't you expect the syntax to be more complicated?
You declared foo as a function of the same type as baz, rather than as a pointer to a function of same type as baz.
From your compiler, the first error message is the useful one - it tells you assignment of function
, i.e. you have tried to assign to a function, which is an error.
I'm not even going to try to write the correct solution without typedefs :-) Here's some code which compiles and I think is right, using typedefs:
#include <stdlib.h>
#include <stdbool.h>
typedef int(*IntReturnsInt)(int);
int inc(int i) { return i+1; }
IntReturnsInt baz(bool b) { return b ? &abs : &inc; }
int main() {
IntReturnsInt (*foo)(bool b);
foo = baz;
}
In this example the double-function-pointer concept is a bit clearer - IntReturnsInt
is a function pointer type and foo
is a pointer to a function which returns IntReturnsInt
... phew :-)
This is a function declaration.
int (*foo(bool))(int);
If you wanted to declare a function pointer, you should do:
int (*(*foo)(bool))(int);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With