Topic: A suspect bug in Visual C++


Author: jcoffin@taeus.com (Jerry Coffin)
Date: 1998/11/30
Raw View
In article <8767c1s375.fsf@pot.cnuce.cnr.it>, F.Potorti@cnuce.cnr.it
says...
>
> Hi,  this is  observed  behaviour on  VC++  4.0, 5.0,  6.0.  The  following
> snippet of  code compiles without  errors under egcs  (as it should,  in my
> opinion), while it generates an error when compiled by VC++.
>
> ---------------------------
> class A {
>     class B {
>         struct C {};
>         friend void f();
>     };
> };
>
> void f() {
>     A::B::C *p;
> }
> ---------------------------
> --> baco_VC.cpp(9) : error C2248: 'C' :
>     cannot access private struct declared in class 'A::B'
>
> I'd like  to hear opinions about whether  this is indeed a  compiler bug or
> else why ever the VC++ compiler classifies this syntax as an error.

IMO, VC++ is right and egcs is wrong in this case.  B is a private
member of A.  f() has been granted access to private members of A::B,
but not of A itself.  Since B is itself a private member of A, the
`friend' declaration should have no real effect.

This is quite a bit like an issue that came up when C was first being
standardized.  Given code like this:

void f() {

 {
  extern void x();

 }

 /* point y */
}

Should the extern statement have any effect at point y or not?  Unless
memory serves me exceptionally poorly today, the decision reached was
that it should not...


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: AllanW@my-dejanews.com
Date: 1998/12/01
Raw View
In article <p6q7lwekzwd.fsf@pandora.inst-inf-1.hu-berlin.de>,
  Martin von Loewis <loewis@informatik.hu-berlin.de> wrote:
>
> Francis Glassborow <francis@robinton.demon.co.uk> writes:
>
> > I think you have to declare friend void f() in both A and B.  Can anyone
> > quote the Standard to justify accepting the code as written?
>
> You don't need access to surrounding classes when defining
> members. [class.access]/6 says:
>
> >> In the definition of a member of a nested class that appears
> >> outside of its class definition, the name of the member may be
> >> qualified by the names of enclosing classes of the member's class
> >> even if these names are private members of their enclosing
> >> classes. [Example:
> >>  class D {
> >>     class E {
> >>       static int m;
> >>     };
> >>  };
> >>  int D::E::m = 1; // OK, no access error on private E
> >> end example]
>
> Otherwise, it seems that you need access to each part of the qualified
> name. Still, the VC++ message is confusing, since it is A::B in the
> original poster's example which cannot be accessed.

You read it wrong! So did I.

[MODERATOR: If possible, please reject my earlier reply. I didn't read
the code properly.]

Inside class A::B, f() was declared as a FRIEND function. And yet the
actual definition of f() wasn't allowed access to a struct which was
defined in A::B.

--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/11/30
Raw View
Martin von Loewis wrote:
>
> Francis Glassborow <francis@robinton.demon.co.uk> writes:
>
> > I think you have to declare friend void f() in both A and B.  Can anyone
> > quote the Standard to justify accepting the code as written?

[...]

> Otherwise, it seems that you need access to each part of the qualified
> name. Still, the VC++ message is confusing, since it is A::B in the
> original poster's example which cannot be accessed.

What about the following similar case?

class A
{
  class B
  {
    struct C {};
    friend void f() { C* p; }
  };
};

Semantically it should be the same (except that f is inline now, of
course).
But is it also the same according to access rules?


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Igor Rafienko <igorr@ifi.uio.no>
Date: 1998/11/30
Raw View
Francesco Potorti` <F.Potorti@cnuce.cnr.it> writes:

| Hi,  this is  observed  behaviour on  VC++  4.0, 5.0,  6.0.  The  following
| snippet of  code compiles without  errors under egcs  (as it should,  in my
| opinion), while it generates an error when compiled by VC++.
|
| ---------------------------
| class A {
|     class B {
|         struct C {};
|         friend void f();
|     };
| };
|
| void f() {
|     A::B::C *p;
| }
| ---------------------------
| --> baco_VC.cpp(9) : error C2248: 'C' :
|     cannot access private struct declared in class 'A::B'
|
| I'd like  to hear opinions about whether  this is indeed a  compiler bug or
| else why ever the VC++ compiler classifies this syntax as an error.

Friendship is not transitive. Nor can it be inherited.


igorR
--
Vy vstaete s posteli, a lezhashaya ryadom devushka hvataet vas za ruku i
govorit:
- Save changes? Yes or No?


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: AllanW@my-dejanews.com
Date: 1998/11/30
Raw View
In article <8767c1s375.fsf@pot.cnuce.cnr.it>,
  Francesco Potorti` <F.Potorti@cnuce.cnr.it> wrote:
>
> Hi,  this is  observed  behaviour on  VC++  4.0, 5.0,  6.0.  The  following
> snippet of  code compiles without  errors under egcs  (as it should,  in my
> opinion), while it generates an error when compiled by VC++.
>
> ---------------------------
> class A {
>     class B {
>         struct C {};
>         friend void f();
>     };
> };
>
> void f() {
>     A::B::C *p;
> }
> ---------------------------
> --> baco_VC.cpp(9) : error C2248: 'C' :
>     cannot access private struct declared in class 'A::B'

I'd say the error message is misleading. The reason that you
cannot acces struct C isn't because it's private to B, but
because B is private to A. So a better error message would
have been:
    'A::B::C': cannot access private class 'B' declared in class 'A'.


--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francesco Potorti` <F.Potorti@cnuce.cnr.it>
Date: 1998/11/28
Raw View
Hi,  this is  observed  behaviour on  VC++  4.0, 5.0,  6.0.  The  following
snippet of  code compiles without  errors under egcs  (as it should,  in my
opinion), while it generates an error when compiled by VC++.

---------------------------
class A {
    class B {
        struct C {};
        friend void f();
    };
};

void f() {
    A::B::C *p;
}
---------------------------
--> baco_VC.cpp(9) : error C2248: 'C' :
    cannot access private struct declared in class 'A::B'

I'd like  to hear opinions about whether  this is indeed a  compiler bug or
else why ever the VC++ compiler classifies this syntax as an error.

Thank you for reading

--
Francesco Potorti` (researcher)        Voice:    +39-050-593 203 (op. 211)
Computer Networks Group                Fax:      +39-050-904052
CNUCE-CNR, Via Santa Maria 36          Email:    F.Potorti@cnuce.cnr.it
56126 Pisa - Italy                     Web:  http://fly.cnuce.cnr.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/11/29
Raw View
I find this an interesting question.  To what is f() being granted
access?
The private interface of class B.  But this is not the same as the
private interface of class A.

I think you have to declare friend void f() in both A and B.  Can anyone
quote the Standard to justify accepting the code as written?


In article <8767c1s375.fsf@pot.cnuce.cnr.it>, Francesco Potorti`
<F.Potorti@cnuce.cnr.it> writes

>Hi,  this is  observed  behaviour on  VC++  4.0, 5.0,  6.0.  The  following
>snippet of  code compiles without  errors under egcs  (as it should,  in my
>opinion), while it generates an error when compiled by VC++.

>---------------------------
>class A {
>    class B {
>        struct C {};
>        friend void f();
>    };
>};

>void f() {
>    A::B::C *p;
>}
>---------------------------
>--> baco_VC.cpp(9) : error C2248: 'C' :
>    cannot access private struct declared in class 'A::B'

>I'd like  to hear opinions about whether  this is indeed a  compiler bug or
>else why ever the VC++ compiler classifies this syntax as an error.



Francis Glassborow      Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Biju Thomas <bijuthom@ibm.net>
Date: 1998/11/29
Raw View
Francis Glassborow wrote:
>
> I find this an interesting question.  To what is f() being granted
> access?
> The private interface of class B.  But this is not the same as the
> private interface of class A.
>
> I think you have to declare friend void f() in both A and B.  Can anyone
> quote the Standard to justify accepting the code as written?

Quote from 11.4/2:

"Declaring a class to be a friend implies that the names of private and
protected members from the class granting friendship can be accessed in
declarations of members of the befriended class."

There is an example too, which elaborates this point in the case of
nested classes:

class A {
  class B { };
  friend class X;
};

class X {
  A::B mx; // ok: A::B used to declare member of X
};

This talks about befriended classes only. But, I think, it extends to
befriended functions too. May be, the wording of the above clause has to
be changed so that it is made explicit in the case of friend functions
too.

Without such a feature, declaring friends of nested classes becomes a
nightmare, as all the containing classes have to have the same friend
declaration. And, having such a friend declaration in the containing
class is dangerous, as it will expose the containing class the friend
class/function unnecessarily.

>
> In article <8767c1s375.fsf@pot.cnuce.cnr.it>, Francesco Potorti`
> <F.Potorti@cnuce.cnr.it> writes
>
> >Hi,  this is  observed  behaviour on  VC++  4.0, 5.0,  6.0.  The  following
> >snippet of  code compiles without  errors under egcs  (as it should,  in my
> >opinion), while it generates an error when compiled by VC++.
>
> >---------------------------
> >class A {
> >    class B {
> >        struct C {};
> >        friend void f();
> >    };
> >};
> >void f() {
> >    A::B::C *p;
> >}
> >---------------------------
> >--> baco_VC.cpp(9) : error C2248: 'C' :
> >    cannot access private struct declared in class 'A::B'

Regards,
Biju Thomas



[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Martin von Loewis <loewis@informatik.hu-berlin.de>
Date: 1998/11/29
Raw View
Francis Glassborow <francis@robinton.demon.co.uk> writes:

> I think you have to declare friend void f() in both A and B.  Can anyone
> quote the Standard to justify accepting the code as written?

You don't need access to surrounding classes when defining
members. [class.access]/6 says:

>> In the definition of a member of a nested class that appears
>> outside of its class definition, the name of the member may be
>> qualified by the names of enclosing classes of the member's class
>> even if these names are private members of their enclosing
>> classes. [Example:
>>  class D {
>>     class E {
>>       static int m;
>>     };
>>  };
>>  int D::E::m = 1; // OK, no access error on private E
>> end example]

Otherwise, it seems that you need access to each part of the qualified
name. Still, the VC++ message is confusing, since it is A::B in the
original poster's example which cannot be accessed.

Regards,
Martin



[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/11/30
Raw View
In article <3661A689.4C80EFFE@ibm.net>, Biju Thomas <bijuthom@ibm.net>
writes
>Without such a feature, declaring friends of nested classes becomes a
>nightmare, as all the containing classes have to have the same friend
>declaration. And, having such a friend declaration in the containing
>class is dangerous, as it will expose the containing class the friend
>class/function unnecessarily.

Off the cuff (its getting late this side of the Atlantic) Why not make
the nested class B a public member of A but without any public members
of its own.  It can befriend the enclosing class A if members of A need
access.

I don't really care because I would deeply suspect code that had private
nested classes declaring friendship to namespace scope functions.
However I was merely responding to the reflex reaction that if VC++
disagrees with any other compiler that it must be wrong.



Francis Glassborow      Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]