VC 8.0: Where is two phase lookup?

S

Stefan Slapeta

There have been many announciations that VC 8.0 will finally support two
phase template lookup; now, after I installing VC 2005 Express I had to
realize that it still doesn't!

What has happend to these plans???


Stefan
 
C

Carl Daniel [VC++ MVP]

Stefan said:
There have been many announciations that VC 8.0 will finally support
two phase template lookup; now, after I installing VC 2005 Express I
had to realize that it still doesn't!

What has happend to these plans???

Where have you seen such an announcement?

-cd
 
S

Stefan Slapeta

Carl said:
Where have you seen such an announcement?

I've not seen it, but I've heard it several times (also from Herb
Sutter); many people in the C++ community are currently ensured that
this feature will be part of the next compiler release!

Stefan
 
C

Carl Daniel [VC++ MVP]

Stefan said:
I've not seen it, but I've heard it several times (also from Herb
Sutter); many people in the C++ community are currently ensured that
this feature will be part of the next compiler release!

I confirmed with the VC++ team that there are no plans to support two-phase
lookup for Whidbey. I've never seen a statement that such support would be
in Whidbey, so I'd be very curious to see a reference to any such claims.

-cd
 
K

krazyman

Carl Daniel said:
I confirmed with the VC++ team that there are no plans to support two-phase
lookup for Whidbey. I've never seen a statement that such support would be
in Whidbey, so I'd be very curious to see a reference to any such claims.

From http://msdn.microsoft.com/chats/vstudio/vstudio_022703.asp

Host: Herb (Microsoft)
Q: What are current plans as far as becoming compliant wrt two-phase
name lookup?

A: That's one of the three things we didn't implement in Everett (the
others were enforcing exception specifications and export). Two-phase
lookup is related to export, so see also the export answer above. One
issue with two-phase lookup is that when we (or any compiler)
provide(s) it, we'll have to consider migration for users -- two-phase
lookup breaks a LOT of existing code, which is one reason it is not
widely implemented in compilers today. (IIRC, EDG supports it in
strict mode, Metrowerks supports it but you need to throw
-iso_templates on (even -ansi strict isn't enough), and IBM used to
support it as an option but no longer does (even as an option). The MW
and IBM situations are because of breaking code.) BTW, I'm giving a
talk about this at SD West in a few weeks, for those who are in the
Bay area and may be interested --
http://www.cmpevents.com/sdw/a.asp?option=3&V=11&SessID=530. (BTW, I
don't know of any other compiler besides those three that does/did
support 2-phase lookup. Did I miss any?)
 
R

Russell Hind

krazyman said:
From http://msdn.microsoft.com/chats/vstudio/vstudio_022703.asp

Host: Herb (Microsoft)
Q: What are current plans as far as becoming compliant wrt two-phase
name lookup?

A: That's one of the three things we didn't implement in Everett (the
others were enforcing exception specifications and export). Two-phase
lookup is related to export, so see also the export answer above. One
issue with two-phase lookup is that when we (or any compiler)
provide(s) it, we'll have to consider migration for users -- two-phase
lookup breaks a LOT of existing code, which is one reason it is not
widely implemented in compilers today. (IIRC, EDG supports it in
strict mode, Metrowerks supports it but you need to throw
-iso_templates on (even -ansi strict isn't enough), and IBM used to
support it as an option but no longer does (even as an option). The MW
and IBM situations are because of breaking code.) BTW, I'm giving a
talk about this at SD West in a few weeks, for those who are in the
Bay area and may be interested --
http://www.cmpevents.com/sdw/a.asp?option=3&V=11&SessID=530. (BTW, I
don't know of any other compiler besides those three that does/did
support 2-phase lookup. Did I miss any?)

I don't read this as 'two-phase look up will be in Whidbey'. Consider
the statement

"One issue with two-phase lookup is that *when we* (or any compiler)
provide(s) it, we'll have to consider migration for users"

Cheers

Russell
 
R

Russell Hind

Can someone point me to a link that describes how two-phase look-up
works, and why implementing it will break current code? I've had a
quick search with google, but haven't come up with much help yet.

Thanks

Russell
 
B

Bo Persson

Russell Hind said:
Can someone point me to a link that describes how two-phase look-up
works, and why implementing it will break current code? I've had a
quick search with google, but haven't come up with much help yet.

The two-phase lookup is used to determine how to find non-dependent
names (not depending on the template parameters) in a template
definition. Accorning to the standard, the lookup should be performed in
the context of the template's not in the context of its use. The
standard document gives this example:

void g(double);

void h();

template<class T> class Z
{
public:
void f()
{
g(1); //calls g(double)
h++; //illformed: cannot increment function;
// this could be diagnosed either here or
// at the point of instantiation
}
};

void g(int); // not in scope at the point of the template
// definition, not considered for the call g(1)



This of course makes the lookup dependent on the order of the
declarations, which is a huge change.


Bo Persson
 
R

Russell Hind

Bo said:
This of course makes the lookup dependent on the order of the
declarations, which is a huge change.

Thanks. I take it then that if the void g(double) hadn't been declared,
that would have been an error as there was no declaration of g before
the template.

This would definitely break some of my code. Even stuff I was 'playing'
with last night, which is a co-incidence!

Cheers

Russell
 
I

Ioannis Vranos

Bo said:
The two-phase lookup is used to determine how to find non-dependent
names (not depending on the template parameters) in a template
definition. Accorning to the standard, the lookup should be performed in
the context of the template's not in the context of its use. The
standard document gives this example:

void g(double);

void h();

template<class T> class Z
{
public:
void f()
{
g(1); //calls g(double)
h++; //illformed: cannot increment function;
// this could be diagnosed either here or
// at the point of instantiation
}
};

void g(int); // not in scope at the point of the template
// definition, not considered for the call g(1)



This of course makes the lookup dependent on the order of the
declarations, which is a huge change.


If I get it correctly, according to the standard void g(int); wouldn't
be considered to be used inside template class Z, however this is the
rational thing to be expected or am I wrong? Doesn't the same already
apply for ordinary class and function definitions?






Regards,

Ioannis Vranos
 
R

Russell Hind

Ioannis said:
If I get it correctly, according to the standard void g(int); wouldn't
be considered to be used inside template class Z, however this is the
rational thing to be expected or am I wrong? Doesn't the same already
apply for ordinary class and function definitions?

For non-template classes yes, if g(double) wasn't declared there would
be an error.

However, for template stuff, the method code isn't really compiled until
you actually use it, so by the time you use it, both

g(double) and
g(int)

have been declared, so which would be called? templates behave
differently from non-template classes because the method compilation
doesn't take place until instantiation.

I think thats correct, anyway.

Thanks

Russell
 
I

Ioannis Vranos

Russell said:
For non-template classes yes, if g(double) wasn't declared there would
be an error.

However, for template stuff, the method code isn't really compiled until
you actually use it, so by the time you use it, both

g(double) and
g(int)

have been declared, so which would be called? templates behave
differently from non-template classes because the method compilation
doesn't take place until instantiation.

I think thats correct, anyway.



It doesn't matter in what stage of the compilation phase they get
compiled, it should matter in which order they were declared.






Regards,

Ioannis Vranos
 
S

Stefan Slapeta

If I get it correctly, according to the standard void g(int); wouldn't
be considered to be used inside template class Z, however this is the
rational thing to be expected or am I wrong? Doesn't the same already
apply for ordinary class and function definitions?

It is not to be expected. Two-phase lookup means that every name which
is not dependent on a template parameter is looked up during _parsing_
the template (also dependent names are looked up if they are
unqualified, but the result set for this lookup is extended during the
second phase, see below). Thus, at the time of parsing this template,
only g(double) can be valid, because nothing of this call (name or
arguments) is dependent on a template parameter.

During the _second_ phase (instantiation of the template), the names for
qualified dependent names are looked up and for unqualified dependent
names, an additional ADL is performed. This is even more interesting if
you consider this example:


void g(float) {}

template<typename T> void f(T t) {
g(t);
}

void g(double) {}

int main() {
f(1);
}


Here, the argument t in g(t) _is_ dependent, but ADL does not add viable
candidates to the overload set. Thus, this call _must not_ be ambigous!
(=my favourite test case on two-phase lookup...)


Stefan
 
I

Ioannis Vranos

Stefan said:
void g(float) {}

template<typename T> void f(T t) {
g(t);
}

void g(double) {}

int main() {
f(1);
}


Here, the argument t in g(t) _is_ dependent, but ADL does not add viable
candidates to the overload set. Thus, this call _must not_ be ambigous!
(=my favourite test case on two-phase lookup...)



However if the above is:

void g(float) {}

template<typename T> void f(T t)
{
g(t);
}

void g(int) {}

int main()
{
f(1);
}


according to the standard, which one should be called?






Regards,

Ioannis Vranos
 
S

Stefan Slapeta

Russell said:
I don't read this as 'two-phase look up will be in Whidbey'. Consider
the statement

"One issue with two-phase lookup is that *when we* (or any compiler)
provide(s) it, we'll have to consider migration for users"

I wouldn't go so far, because such a strategy seems quite impossible to
me. I think it would be sufficient for all users if there is an optional
switch that turns on two-phase lookup (which can be disabled as
default). It is a simple fact that you can't guarantee that your code is
standard conformant if your compiler doesn't complain about issues
caused by incorrect declaration order in your code!

The better reason for not implementing it is, as I assume, that it would
strongly decrease compiler performance (because you have to parse
templates you normally wouldn't).

Stefan
 
S

Stefan Slapeta

Ioannis said:
However if the above is:

void g(float) {}

template<typename T> void f(T t)
{
g(t);
}

void g(int) {}

int main()
{
f(1);
}


according to the standard, which one should be called?

It's the same - the second g is no candidate for the overload set (it's
not seen at the time of parsing the template).

Stefan
 
I

Ioannis Vranos

Stefan said:
It's the same - the second g is no candidate for the overload set (it's
not seen at the time of parsing the template).



OK then, it seems I haven't understood yet. So what would be different
with the two phases?






Regards,

Ioannis Vranos
 
C

Carl Daniel [VC++ MVP]

krazyman said:
"Carl Daniel [VC++ MVP]"
I confirmed with the VC++ team that there are no plans to support
two-phase
lookup for Whidbey. I've never seen a statement that such support
would be
in Whidbey, so I'd be very curious to see a reference to any such
claims.

From http://msdn.microsoft.com/chats/vstudio/vstudio_022703.asp

Thanks for the link. I participated in that chat - it might have been me
that asked the question about two-phase lookup in fact. There's clearly no
indication in that chat that two-phase lookup would be in Whidbey, only a
reasonably clear statement that two-phase lookup is related to export and
that MS would consider implementing it when there's sufficient market demand
for it, at that time providing a smooth migration path becasue two-phase
lookup will break a lot of code.

-cd
 
B

Bo Persson

Ioannis Vranos said:
OK then, it seems I haven't understood yet. So what would be different
with the two phases?

The big difference is that different sets of overloads can be seen at
different points of use of the template. They should all be using the
same g(float) anyway. This isn't considered in most of existing code.

I have heard stories about when HP first tried to implement this, and
almost nothing would compile, not even the standard library. It took
them a while to realize that the compiler was actually right, and that
they immediately had to add a switch to turn the new features off!


Bo Persson
 
S

Stefan Slapeta

Bo said:
The big difference is that different sets of overloads can be seen at
different points of use of the template. They should all be using the
same g(float) anyway. This isn't considered in most of existing code.

I have heard stories about when HP first tried to implement this, and
almost nothing would compile, not even the standard library. It took
them a while to realize that the compiler was actually right, and that
they immediately had to add a switch to turn the new features off!

I think that all these statements are quite exaggerated; from my
experience, the impact on existing projects normally is quite small.

BTW, with two-phase lookup turned on, the 7.1 standard lib compiles
without any problems if you just make two very small patches (one in
xdebug and on in xlocale).


Stefan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top