Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can `f();` be a declaration below?

Excerpt from DR 1990:

In an example like

void f() {
    f();  // #1
}

The statement at #1 is ambiguous and can be parsed as either an expression or as a declaration.

like image 1000
Ayrosa Avatar asked Apr 21 '16 11:04

Ayrosa


Video Answer


1 Answers

This is basically a technical issue with how the grammar was written. No sane vendor will actually report an ambiguity here.

In C++14 and earlier, we have a simple-declaration being, among other things,

decl-specifier-seqopt init-declarator-listopt ;

Note that the decl-specifier-seq was optional.

Then we have a semantic requirement that the decl-specifier-seq can only be omitted in a constructor, destructor, or conversion function declaration, but that doesn't affect parsing.

A simple-declaration is a block-declaration, and a block-declaration is a declaration-statement, so the net effect is that in a compound-statement like

{
    f();
}

f(); can be parsed either as a declaration-statement consisting of an (ill-formed) simple-declaration that has no decl-specifier-seq, or as an expression-statement.

The DR1990 change makes the decl-specifier-seq required in the simple-declaration production, and creates a separate nodeclspec-function-declaration production that is not a block-declaration for the no decl-specifier-seq case, so that the f(); as-an-ill-formed-declaration parse is no longer possible inside a compound-statement.

like image 167
T.C. Avatar answered Oct 19 '22 12:10

T.C.