Search code examples
c++c++17language-lawyercompiler-specificalias-declaration

Are nested parentheses allowed in function type alias declaration?


The following code can be compiled with gcc-13 and clang-16, but MSVC reports multiple errors

using foo_type = void ((((int, const char*))));   // (1)
// Compiler messages for line (1):
//    clang-16: ok.
//    gcc-13:   ok.
//    MSVC-v19: error C2062: type 'int' unexpected.


foo_type foo;

int main()
{
    foo(5, "Hello");
    return 0;
}

The question is: who's right? Does the Standard allow alias-declaration of a function type with multiple nested parentheses around argument list, like attempted in the example above?


Solution

  • Yes, that syntax is allowed and not specific to alias declarations. It applies to all declarators.

    You can generally put as many parentheses around a declarator as you want. In the case of an abstract-declarator such as here, nothing changes, except that the declarator-id (i.e. the name) is omitted. An exception are declarators with a trailing-return-type.

    For example, the following is also valid:

    void (((foo(int, const char*))));
    
    int main()
    {
        foo(5, "Hello");
        return 0;
    }
    

    For the same reason you can also add parentheses around the * abstract-declarator in the function parameter:

    using foo_type = void ((((int, const char(((*)))))));
    

    Specifically for the tag, see the grammar production ( ptr-declarator ) for noptr-declarator in the non-abstract case and ( ptr-abstract-declarator ) for noptr-abstract-declarator in the abstract case.