Reputation: 3513
I know I'm being pedantic here, but I'm just trying to understand the C++ grammar production.
I will start with a simple-declaration.
simple-declaration:
decl-specifier-seqopt init-declarator-listopt
decl-specifier-seq:
decl-specifier
decl-specifier:
type-specifier
type-specifier:
trailing-type-specifier
trailing-type-specifier:
simple-type-specifier
simple-type-specifier:
char
int
...
auto
Now, I'll look into the definition of a init-declarator-list.
init-declarator-list:
init-declarator
init-declarator:
declarator
declarator:
noptr-declarator parameters and qualifiers trailing return type (*2)
noptr-declarator:
declarator-id attribute-specifier-seqopt
noptr-declarator parameters and qualifiers (*1)
parameters and qualifiers:
(parameter-declaration-clause) cv-qualifiersopt ... (all optionals)
trailing-return-type:
-> trailing-type-specifier-seq
trailing-type-specifier-seq:
trailing-type-specifier See the definition of a traling-type-specifier above.
Replacing noptr-declarator by a declarator-id in (*1), using the previous definition of noptr-declaration, we arrive at the following definition of nonptr-declarator:
noptr-declaration:
declarator-id parameters and qualifiers
Now replacing noptr-declarator, parameters and qualifiers and trailing-return-type in (*2) by each definition given above, we obtain the following for declarator:
declarator:
declarator-id (parameter-declaration-clause) (parameter-declaration-clause) ->
simple-type-specifier
With this last result we could say that the grammar allows the following declaration of a function f
:
auto f()() -> int;
which of course is not valid. But I couldn't find anything in the Standard saying, directly or indirectly, that this construction is ill-formed.
The error messages from GCC
(f
declared as function returning a function) and clang
(auto
return without trailing return type; deduced return types are a C++1y extensions) didn't help in this regard either.
Upvotes: 4
Views: 327
Reputation: 4031
In fact, the gcc error message is quite helpful: The grammar does in fact allow auto f()() -> int
, but this syntactically correct declaration is semantically invalid. It would describe a function returning a function returning int
. See the answer of ecatmur for the standard quote disallowing that.
To understand the parse, work like this. f
is what you want to declare. Parse to the right, you'll find an empty argument list, so f()
is a valid expression, and the type of that expression gets declared. Parse again to the right, you'll find an argument list again, so the return type of f
is a function taking zero arguments. Parse again to the right, and you will hit the end (the ->
arrow), so parse to the left to find the result type, which is auto, and gets replaced by the type past the arrow.
Upvotes: 9
Reputation: 157364
[dcl.fct]/8:
[...] Functions shall not have a return type of type array or function, although they may have a return type of type pointer or reference to such things. [...]
Upvotes: 11