简体   繁体   中英

Where in the Standard does it say that the declaration `auto f()() ->int;` is not allowed?

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-seq opt init-declarator-list opt

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-seq opt
noptr-declarator parameters and qualifiers (*1)

parameters and qualifiers :
( parameter-declaration-clause ) cv-qualifiers opt ... (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.

[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. [...]

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM