Topic: Template name lookup problem


Author: comeau@panix.com (Greg Comeau)
Date: Tue, 13 Nov 2001 22:48:12 GMT
Raw View
In article <7dc3b1ea.0111121523.3c95a1c1@posting.google.com>,
Peter Dimov <pdimov@mmltd.net> wrote:
>The online Comeau rejects this code:
>
>namespace N
>{
>}
>
>template<class T> struct X
>{
>  enum { value = sizeof(N::f((T*)0)) };
>};
>
>claiming that
>
>"22381.c", line 7: error: namespace "N" has no member "f"
>    enum { value = sizeof(N::f((T*)0)) };
>                             ^
>OK, but N::f depends on a template parameter. N will contain an
>appropriate 'f' when X is instantiated.
>
>Is Comeau right?

Not all templates issues are resolved at instantiation time.
As more compilers get more compliant (especially as Koenig lookup
and dependent name looks are properly implemented), template code
which make assumptions will break.  For some code, this will be
a real real nuisance.
--
Greg Comeau         export ETA: December     See our Oct 31st special
Comeau C/C++ ONLINE ==>     http://www.comeaucomputing.com/tryitout
World Class Compilers:  Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Anthony Williams" <anthwil@nortelnetworks.com>
Date: Wed, 14 Nov 2001 10:18:30 GMT
Raw View
"Peter Dimov" <pdimov@mmltd.net> wrote in message
news:7dc3b1ea.0111121523.3c95a1c1@posting.google.com...
> The online Comeau rejects this code:
>
> namespace N
> {
> }
>
> template<class T> struct X
> {
>   enum { value = sizeof(N::f((T*)0)) };
> };
>
> claiming that
>
> "22381.c", line 7: error: namespace "N" has no member "f"
>     enum { value = sizeof(N::f((T*)0)) };
>                              ^
> OK, but N::f depends on a template parameter. N will contain an
> appropriate 'f' when X is instantiated.
>
> Is Comeau right?

14.6.2p1:

"In an expression of the form:

postfix-expression ( expression-list-opt )

where the postfix-expression is an identifier, the identifier denotes a
dependent name if and only if any of the expressions in the expression-list
is a type-dependent expression (14.6.2.2)."

14.6.2.2 says that "(type-id) cast-expression" is dependent "only if the
type specified by the type-id, ... is dependent".

T* is a dependent type because (from 14.6.2p1) it is "a compound type
constructed from any dependent type,"

Therefore f((T*)0)) would be a type-dependent expression, but N::f((T*)0)
isn't, as N::f is a qualified id, not a plain identifier. Therefore Comeau
is right.

I'm not sure I like it, but that's the way it appears to be.

Anthony
--
Anthony Williams
Software Engineer, Nortel Networks Optical Components Ltd
The opinions expressed in this message are not necessarily those of my
employer



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Valentin.Bonnard@free.fr (Valentin Bonnard)
Date: Thu, 15 Nov 2001 11:10:04 GMT
Raw View
Peter Dimov wrote:
> The online Comeau rejects this code:
>
> namespace N
> {
> }
>
> template<class T> struct X
> {
>   enum { value = sizeof(N::f((T*)0)) };
> };
>
> claiming that
>
> "22381.c", line 7: error: namespace "N" has no member "f"
>     enum { value = sizeof(N::f((T*)0)) };
>                              ^
> OK, but N::f depends on a template parameter. N will contain an
> appropriate 'f' when X is instantiated.
>
> Is Comeau right?

You mean, is Comeau following the standard   ? Mu.

At least I cannot make any sens of the standard on this.

But your code is very clearly valid, even if writing N::f
before any N::f is defined makes me feel strange. So you
want feel a bug report, but Comeau may prefer to delay it
until the standard is fixed.

Note: We aren't amazed. Well, we aren't *so* amazed. We
already knew dependent name resolution was broken (to be
honnest, it comes to a surprise, to me, that it is so
badly broken).

  --   VB

PS: I really feel this is anotehr symptom of the dependent
name resolution = dependent name lookup syndrom (those two
are very different   !)

PPS: How did we voted this half-baked standard   ? (ISO NB:
for: 8, against: 0, abst: 0)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: pdimov@mmltd.net (Peter Dimov)
Date: Thu, 15 Nov 2001 18:42:34 GMT
Raw View
Valentin.Bonnard@free.fr (Valentin Bonnard) wrote in message news:<200111150359.EAA09512@brick.ens.fr>...
> Peter Dimov wrote:
> > The online Comeau rejects this code:
> >
> > namespace N
> > {
> > }
> >
> > template<class T> struct X
> > {
> >   enum { value = sizeof(N::f((T*)0)) };
> > };
> >
> > claiming that
> >
> > "22381.c", line 7: error: namespace "N" has no member "f"
> >     enum { value = sizeof(N::f((T*)0)) };
> >                              ^
> > OK, but N::f depends on a template parameter. N will contain an
> > appropriate 'f' when X is instantiated.
> >
> > Is Comeau right?
>
> You mean, is Comeau following the standard   ? Mu.
>
> At least I cannot make any sens of the standard on this.

:-)

> But your code is very clearly valid, even if writing N::f
> before any N::f is defined makes me feel strange.

Well, I can't declare the appropriate 'f' before its corresponding class is defined:

class Y
{
  enum { id = 5 };
  typedef char (&tag) [id];
};

namespace N
{
  Y::tag f(Y*);
}

// now use X<Y>::value

> So you
> want feel a bug report, but Comeau may prefer to delay it
> until the standard is fixed.

A defect report, perhaps.

--
Peter Dimov
Multi Media Ltd.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: Thu, 15 Nov 2001 21:18:59 GMT
Raw View
Valentin Bonnard wrote:
>
> Peter Dimov wrote:
> > The online Comeau rejects this code:
> >
> > namespace N
> > {
> > }
> >
> > template<class T> struct X
> > {
> >   enum { value = sizeof(N::f((T*)0)) };
> > };
> >
> > claiming that
> >
> > "22381.c", line 7: error: namespace "N" has no member "f"
> >     enum { value = sizeof(N::f((T*)0)) };
> >                              ^
> > OK, but N::f depends on a template parameter. N will contain an
> > appropriate 'f' when X is instantiated.
> >
> > Is Comeau right?
>
> You mean, is Comeau following the standard ? Mu.
>
> At least I cannot make any sens of the standard on this.
>
> But your code is very clearly valid, even if writing N::f
> before any N::f is defined makes me feel strange. So you
> want feel a bug report, but Comeau may prefer to delay it
> until the standard is fixed.

The other three people who've responded to this message all said that
the code was invalid. Two of them presented detailed arguments
containing citations from apparantly relevant sections of the standard.
Could you explain your counter argument?

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: pdimov@mmltd.net (Peter Dimov)
Date: Tue, 13 Nov 2001 01:46:07 GMT
Raw View
The online Comeau rejects this code:

namespace N
{
}

template<class T> struct X
{
  enum { value = sizeof(N::f((T*)0)) };
};

claiming that

"22381.c", line 7: error: namespace "N" has no member "f"
    enum { value = sizeof(N::f((T*)0)) };
                             ^
OK, but N::f depends on a template parameter. N will contain an
appropriate 'f' when X is instantiated.

Is Comeau right?

--
Peter Dimov
Multi Media Ltd.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Michiel Salters<Michiel.Salters@cmg.nl>
Date: Tue, 13 Nov 2001 19:21:08 GMT
Raw View
In article <7dc3b1ea.0111121523.3c95a1c1@posting.google.com>, Peter Dimov
says...
>
>The online Comeau rejects this code:
>
>namespace N { }
>
>template<class T> struct X
>{
>  enum { value = sizeof(N::f((T*)0)) };
>};
>
>claiming that
>
>"22381.c", line 7: error: namespace "N" has no member "f"
>    enum { value = sizeof(N::f((T*)0)) };
>                             ^
>OK, but N::f depends on a template parameter. N will contain an
>appropriate 'f' when X is instantiated.
>
>Is Comeau right?

T is clearly type dependant. That makes (T*)0 a "Type-dependent expression"
[ 14.6.2.2 ] because of bullet 3:
" An id-expression is type-dependent if it contains:
an identifier that was declared with a dependent type, ..."

By 14.6.2 "In an expression of the form:
postfix-expression ( expression-list opt )
where the postfix-expression is an identifier, the identifier denotes a
dependent name if and only if any of the expressions in the
expression-list is a type-dependent expression (14.6.2.2). "

This makes N::f a dependent name. Therefore the applicable name lookup is
described in [temp.dep.res] 14.6.4 Dependent name resolution:"
1 In resolving dependent names, names from the following sources are considered:
Declarations that are visible at the point of definition of the template.
Declarations from namespaces associated with the types of the function
arguments both from the instantiation context (14.6.4.1) and from the
definition context. "

The second dash doesn't apply to N::f, which leaves only one context, that
of the template definition. In that context no N::f is declared.

14.6.4.2 doesn't apply because N::f is a "qualified-id".

So Comeau is correct in looking up N::f in the template definition scope
only.

Regards,

--
Michiel Salters
Consultant Technical Software Engineering
CMG Trade, Transport & Industry
Michiel.Salters@cmg.nl

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]