Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++0x: resolving ambiguity between function-definition followed by empty-declaration and simple-declaration

I am having an issue with wrapping my head around an apparent ambiguity in the c++0x spec, see also: http://www.nongnu.org/hcb/

Assume we have the code

void foo() {};

Personally I interpret the code as a function-definition followed by an empty-declaration. But, looking at the grammar spec, I'd say that this could just as easily be interpreted as a simple-declaration, which is part of block-declaration and hence mentioned sooner in the list of declaration...

Here's my explanation for how this can be parsed as a simple-declaration:

void foo() {};"

-> simple-declaration

void

-> decl-specifier-seq -> decl-specifier -> type-specifier -> trailing-type- specifier -> simple-type-specifier

foo() {}

-> init declarator-list -> init-declarator

foo()

-> declarator -> ptr-declarator -> noptr-declarator

foo

-> declarator-id -> ...

()

-> parameters-and-qualifiers

{} 

-> initializer -> braced-init-list

So this should be possible to be parsed as a simple-declaration.

I was told that 6.8 of the spec should be used to disambiguate this case, but I don't quite understand why. Is a simple-declaration an expression-statement since it ends with an ;?

like image 340
milianw Avatar asked Aug 11 '11 17:08

milianw


1 Answers

I think you are right. It's an ambiguity and I'm not aware of a paragraph that resolves it in the spec.

There are other ambiguities in the C++0x spec that are not explicitly resolved, but that (hopefully) are going to be implemented in the straight forward way by compilers. For example, the following can be parsed as both the definition of a nested class B and as the definition of an unnamed bitfield having size 0 of the underlying type struct B. The latter interpretation would render the program invalid).

struct C { constexpr operator int() { return 0; } }; 
struct A { struct B : C { }; };

Another example

struct A {
  // is 0 a 'brace-or-equal-initializer' or a 'pure-specifier'?
  virtual void f() = 0;
};

Clang recently had to fix the following because it got it the wrong way (it parsed it as initializing a variable f, instead of making a function pure).

typedef void T();
struct B : A {
  // B::f overrides A::f
  T f = 0;
};
like image 109
Johannes Schaub - litb Avatar answered Nov 03 '22 10:11

Johannes Schaub - litb