Re: Class templates and friend function templates

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



<google@xxxxxxxxxxxxxxx> wrote in message
news:1122471192.878354.184640@xxxxxxxxxxxxxxxxxxxxxxxxxxxx
John Carson wrote:
[...]
VC++, on the other hand, is doing at least two things wrong:

Our (EDG) compiler has a "Microsoft bugs" mode that also emulates this. I looked it up in our documentation...

1. It is instantiating an instance of the operator from

template <class U, class V>
bool operator == (C<U>& u, C<V> &v)
{
     cout << c0.x;
     return u.x == v.x;
}

when it should instead be producing a link error for the more
specialised form of the operator declared in the friend declaration.

2. It is granting this operator friendship rights that it shouldn't
have.

While this is true, they are both the consequence of the same bug: Microsoft compilers seem to treat friend function declarations as what used to be known as "guiding function declarations". (I meant to write about those in the "C++ Templates" book, but it somehow never made it into the text.) A "guiding function declaration" was a declaration of an instance of a template. It was different from an explicit specialization in that it did not inhibit the instance from being generated.

You mean being generated from the general template.

(The ARM hints at the existence of guiding
functions and for a while they were formally specified in the
Working Paper that eventually became the C++ standard. They were
removed from the standard when the notion of "signature" was
finalized, if I remember correctly.)

So what's happening in the example is that the friend declaration
injected by MSVC++ is _not_ equivalent to

 template<typename Other>
   bool operator==(C<int>&, C<Other>&);

but to some other construct that can no longer be expressed in
standard C++ (and in fact, I don't think the parameterized form
was ever possible).  For argument's sake:

 __guide template<typename Other>
   bool operator==(C<int>&, C<Other>&);

This "guiding declaration" gets matched to a template declaration
that _follows_  it (a rather funny concept for C++, IMO).  The final
result is that a subset of instances is made a friend of the class,
which is in fact what the original poster wanted.  You can verify
this by replacing "C<Other>" in the friend declaration by "C<Other*>":
I think that will result in access errors.

Nope. Replacing C<Other> with C<Other*> makes no difference. Friendship seems to be granted without restriction to every instantiation of the operator. This is true of both VC++ 7.1 and VC++ 8.0 Beta 2. This suggests to me that there is more than one bug involved though, as you indicate below, the mechanism underlying observed behaviour is difficult to infer.


(Note that this analysis is based on observation alone.  The MSVC++
compiler may very well work completely differently internally.)

As you can imagine, figuring out that kind of stuff and emulating
the associated bugs in an otherwise standard compiler is loads of
fun ;-)

Daveed


--
John Carson


.



Relevant Pages

  • Re: Template friendship to nested template class
    ... While not officially part of the standard, ... compilers incorporate DR45. ... with the friend declaration removed completely. ...
    (microsoft.public.vc.language)
  • Function typedef and __declspec(noreturn)
    ... The following declaration ... compiles fine with VC 7.1 but produces the following error ... function declarations or definitions ... Given that the __declspecis not standard I cannot ask ...
    (microsoft.public.vc.language)
  • Re: If you could change the C or C++ or Java syntax, what would you like different?
    ... This clearly contradicts multiple examples of how the C standard uses ... a typedef name is declared and defined by a "typedef ... Note that each of the above is a declaration and a definition ... I claim that a programming language is similar to the English ...
    (comp.lang.c)
  • Re: Tentative definition versus external linkage
    ... "The Standard model is a combination of features of the strict ref/def ... appropriate declaration without storage class specifier, ... A definition of an identifier is a declaration for that ...
    (comp.lang.c)
  • Tentative definition versus external linkage
    ... I'm having some trouble understanding the rationale for C99 when it ... "The Standard model is a combination of features of the strict ref/def ... appropriate declaration without storage class specifier, ...
    (comp.lang.c)