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.

Share:
10,802
Andy Balaam
Author by

Andy Balaam

Updated on July 24, 2022

Comments

  • Andy Balaam
    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
    GManNickG over 10 years
    This is what typedef's are for. I would deny anyone from checking in code like this with great vengeance and furious anger.
  • Andy Balaam
    Andy Balaam over 10 years
    Agreed - I would always use a typedef.
  • John Bode
    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, assume typedef void retfn(int); ... retfn *myfn(void) {...}. The typedef retfn 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
    John Bode over 10 years
    I will say that callfn()(1); is just bad manners; you could at least assign the result of callfn to a temporary and call through that temporary (especially if callfn can potentially return NULL).
  • GManNickG
    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
    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 returns void and takes void as a parameter list, and I get all of that from that one prototype. No need to look anywhere else.
  • Andy Balaam
    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
    CB Bailey about 9 years
    g++'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) taking int 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
    Andy Balaam about 9 years
    @CharlesBailey thanks, that helps explain the message from g++.
  • BЈовић
    BЈовић almost 9 years
    I will +1, if you add an example with typedef. The syntax without a typedef looks awful.