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 ;
?
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;
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With