c++g++most-vexing-parse

Intended local function forward declaration


GCC warns you by default when it parses your code as function declaration when it could be a variable definition. It also recommends you ways to fix the warning, if your intention was variable definition. But how to fix it, if your intention was actually function declaration?

Is local function declaration deprecated in C++? Is Foo f(void); a good a legal way to forward declare a function? Is it a place for GCC improvement?

#include <iostream>

struct Foo {};

int main()
{
    Foo f();
    f();
    return 0;
}

Foo f()
{
    std::cout << "f() called" << std::endl;
    Foo foo;
    return foo;
}
vexing-parse.cpp: In function ‘int main()’:
vexing-parse.cpp:7:10: warning: empty parentheses were disambiguated as a function declaration [-Wvexing-parse]
    7 |     Foo f();
      |          ^~
vexing-parse.cpp:7:10: note: remove parentheses to default-initialize a variable
    7 |     Foo f();
      |          ^~
      |          --
vexing-parse.cpp:7:10: note: or replace parentheses with braces to aggregate-initialize a variable

UPD: Re what IMO could be improved in GCC:


Solution

  • In order to treat Foo f(); as a function declaration, you can add void to the parameter list like:

    int main()
    {
        Foo f(void);
        f();
        return 0;
    }
    

    The presence of void makes a variable definition invalid so it reverts back to treating it as a function declaration which you can see working in this live example.