What does "error: ’myfn’ declared as function returning a function" mean?
10,802
You are allowed to return a function pointer, and the correct syntax looks like this:
void (*myfn())(int)
{
}
Complete example:
#include <cstdio>
void retfn(int) {
printf( "retfn\n" );
}
void (*callfn())(int) {
printf( "callfn\n" );
return retfn;
}
int main() {
callfn()(1); // Get back retfn and call it immediately
}
Which compiles and runs like this:
$ g++ myfn.cpp && ./a.out
callfn
retfn
If anyone has a good explanation for why g++'s error message suggests this is not possible, I'd be interested to hear it.
Author by
Andy Balaam
Updated on July 24, 2022Comments
-
Andy Balaam almost 2 years
I am trying to write a function that returns a function pointer. Here is my minimal example:
void (*myfn)(int)() // Doesn't work: supposed to be a function called myfn { // that returns a pointer to a function returning void } // and taking an int argument.
When I compile this with
g++ myfn.cpp
it prints this error:myfn.cpp:1:19: error: ‘myfn’ declared as function returning a function myfn.cpp:1:19: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11 [enabled by default]
Does this mean I am not allowed to return a function pointer?
-
GManNickG over 10 yearsThis is what
typedef
's are for. I would deny anyone from checking in code like this with great vengeance and furious anger. -
Andy Balaam over 10 yearsAgreed - I would always use a typedef.
-
John Bode over 10 years@GManNickG: The problem with using a
typedef
is that it can hide some information that would be useful. For example, assumetypedef void retfn(int); ... retfn *myfn(void) {...}
. The typedefretfn
doesn't tell me what the pointed-to function returns, or what parameters it takes, or that it's even callable ("fn" may be obvious to me, but not someone else). If the typedef is in a header somewhere, I have to go look it up to get that info. I'd rather have that information up front. I've cooled on typedefs for this reason. -
John Bode over 10 yearsI will say that
callfn()(1);
is just bad manners; you could at least assign the result ofcallfn
to a temporary and call through that temporary (especially ifcallfn
can potentially returnNULL
). -
GManNickG over 10 years@JohnBode: You're only switching from "You'd have to look at the typedef" to "you'll need to look at the function", as far as I can tell. What's the difference? That's what descriptive names are for, anyway.
typedef void disconnect_callback_function(); disconnect_callback_function get_disconnect_callback_function();
-
John Bode over 10 years@GManNickG: The difference is that
void (*get_disconnect_callback_function())(void)
gives me all the information I need up front. I know that it not only returns a pointer to a function, I know that the pointed-to function returnsvoid
and takesvoid
as a parameter list, and I get all of that from that one prototype. No need to look anywhere else. -
Andy Balaam over 10 years@JohnBode I guess the fact that I felt the need to add a comment suggests I felt I was being a little rude :)
-
CB Bailey about 9 yearsg++'s error message is partially correct. You cannot return a function (or an array) from a function, only a pointer to an array or a function. It's seems that
myfn
is declared in the question to be a pointer to a function returning a function (bad) takingint
returning another function (bad, again) taking no arguments. Of course, you cannot provide a function body as definition to a pointer to function but perhaps g++ didn't get as far as that error. -
Andy Balaam about 9 years@CharlesBailey thanks, that helps explain the message from g++.
-
BЈовић almost 9 yearsI will +1, if you add an example with typedef. The syntax without a typedef looks awful.