Re: C++ Grammar - Update

Martin von Loewis <>
13 May 2001 01:14:25 -0400

          From comp.compilers

Related articles
C++ Grammar - Update (Mike Dimmick) (2001-04-26)
Re: C++ Grammar - Update (Martin von Loewis) (2001-04-30)
Re: C++ Grammar - Update (Ira D. Baxter) (2001-05-03)
Re: C++ Grammar - Update (Mike Dimmick) (2001-05-03)
Re: C++ Grammar - Update (Patrice Gahide) (2001-05-03)
Re: C++ Grammar - Update (Michael Spencer) (2001-05-07)
Re: C++ Grammar - Update (Michael Spencer) (2001-05-13)
Re: C++ Grammar - Update (Martin von Loewis) (2001-05-13)
| List of all articles for this month |

From: Martin von Loewis <>
Newsgroups: comp.compilers,
Date: 13 May 2001 01:14:25 -0400
Organization: Humboldt University Berlin, Department of Computer Science
References: 01-04-141 01-04-155 01-05-008
Keywords: C++, parse
Posted-Date: 13 May 2001 01:14:25 EDT

"Mike Dimmick" <> writes:

> > There are actually ambiguities in this area, consider
> >
> > class X{
> > friend A::B::C();
> > };
> >
> > Is this ::C, returning A::B, or is it ::B::C, returning A? This is
> > currently an ambiguity in C++, which is not resolved in the '98
> > edition of the standard.
> I'm not sure that is actually an ambiguity - it depends on the types
> in question.

To give a more complete example, consider

struct A{
    struct B{};

A::B C();

namespace B{
    A C();

struct Test{
    friend A::B ::C();

This is from the C++ core issues list, see

> Remember that it says that '[a] type definition introduces a new
> keyword.'

Where does it say that? Searching the standard for this phrase, I
found no occurrences.

> If A is a class or a namespace

It is.

> , and B is a class or namespace

It is both: A::B is a class, and ::B is a namespace.

> it names the function C() in A::B.

What is 'it' here? A::B names a type, namely the return type of ::C.
A names the return type of ::B::C.

> It's then a syntax error by my terms because there's no return type.

That is the third way to read it. With two derivations from the
grammar start symbol that are successful, there is no point in
considering the unsuccessful parses...

> In the first case, if there is no C() in A::B, it's a semantic error.
> C++ parsing involves a fair amount of 'in what possible way could this
> be correct?'.

Where does it say that?

> I note that section 7 para 2 of the standard says: "The longest
> sequence of _decl-specifiers_ that could possibly be a type name is
> taken as the _decl-specifier-seq_ of a declaration."

That does not help: the first decl-specifier is friend. The second
decl-specifier could be either A, or A::B (either parses as a
simple-type-specifier). So the sequence of decl-specifiers has the
length 2 in either interpretation.

> That depends on whether A has been previously declared. If you have
> the declaration
> template <int c>
> class A {
> enum B { D = c, E };
> };
> then A<k>::B is a type.

No, it isn't. There could be a specialization A<3> where A<3>::B is an
integer constant. If you know the value of k, you can tell. If k is a
template parameter itself, A<k>::B will be considered as an object,
not as a type.

> "The definition of an explicitly specialized class is unrelated to the
> definition of a generated specialization. That is, its members need
> not have the same names, types, etc. as the members of the a generated
> specialization."

That exactly says it: you *cannot* tell whether A<k>::B is a type or
not, by looking at A alone (i.e. know knowing what k is). Instead, you
look at the syntax only, and whether there is the typename keyword or
not. 14.6, [temp.res]/2 says

# A name used in a template declaration or definition and that is
# dependent on a template-parameter is assumed not to name a type
# unless the applicable name lookup finds a type name or the name is
# qualified by the keyword typename.


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.