Topic: Access control
Author: James.Kanze@dresdner-bank.com
Date: 1999/05/30 Raw View
In article <374BE6B0.C5655E6C@physik.tu-muenchen.de>,
Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
> What about:
>
> B::B():
> A(B())
> {
> }
>
> This will lead to infinite recursion at runtime, but it
> will not give undefined behaviour. It's not any more useful than
> your version, but at least it isn't allowed to format your
> hard disk ;-)
Isn't it? I believe that exceeding implementation limits is also
undefined behavior.
--
James Kanze mailto:
James.Kanze@dresdner-bank.com
Conseils en informatique orient e objet/
Beratung in objekt orientierter
Datenverarbeitung
Ziegelh ttenweg 17a, 60598 Frankfurt, Germany Tel. +49 (069) 63 19 86
27
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
---
[ 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: 1999/05/26 Raw View
Philip Gibbs wrote:
>
> In article <7hvum9$4bb$1@nnrp1.deja.com>, Andrei Alexandrescu
> <andrewalex@hotmail.com> writes
> >
> >Let's analyze this code:
> >
> >class A
> >{
> > A();
> >};
> >
> >class B : public A
> >{
> >public:
> > B();
> >};
> >
> >B::B()
> >{
> >}
> >
> >B var;
> >
> >The code is in error, because B's default constructor will implicitly
> >call A's default constructor, which is private.
> >
> >The question is: when should the compiler generate an error? This is a
> >no-nonsense question, please take it seriously.
> >
> >1. At B::B()'s declaration
> >2. At B::B()'s definition
> >3. At var's definition
>
> 2. I would expect it at B::B()'s definition because this
> uses the private constructor A::A() which is illegal here.
>
> >
> >Is there any guarantee on *where* the error will be generated?
>
> I don't think there even has to be a concept of where in the code
> a compile time error is generated.
>
> >Put another way: if you comment out var's definition, will the code be
> >valid?
>
> No, and with good reason. A similar variable declaration might
> appear in another file where the definition of B::B() is not
> included. Separate compilation would therefore be impossible
> if the code was allowed to be valid.
>
> >If not, and if you comment B::B's definition, will the code be
> >valid?
>
> Yes. The definition of B::B() could be in another source file
> and could be valid if it used the copy constructor of A instead
> of the default constructor. The copy constructor would have to
> construct from an object of a class derived from A (e.g. B)
> because objects
>
> I know the following is useless but it is well formed
> code giving an alternative definition of B::B() which will
> produce no compile time error
>
> B b;
> B::B():
> A(b)
> {
> }
>
> I think the result must be undefined since b is constructed
> using itself. I can't see a way of producing a definition
> of B::B() which would not have undefined behaviour but it
> would be a clever compiler which could deduce as much from
> the class definitions.
What about:
B::B():
A(B())
{
}
This will lead to infinite recursion at runtime, but it
will not give undefined behaviour. It's not any more useful than
your version, but at least it isn't allowed to format your
hard disk ;-)
[ 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: Andrei Alexandrescu <andrewalex@hotmail.com>
Date: 1999/05/20 Raw View
Let's analyze this code:
class A
{
A();
};
class B : public A
{
public:
B();
};
B::B()
{
}
B var;
The code is in error, because B's default constructor will implicitly
call A's default constructor, which is private.
The question is: when should the compiler generate an error? This is a
no-nonsense question, please take it seriously.
1. At B::B()'s declaration
2. At B::B()'s definition
3. At var's definition
Is there any guarantee on *where* the error will be generated?
Put another way: if you comment out var's definition, will the code be
valid? If not, and if you comment B::B's definition, will the code be
valid?
I looked the standard up, but without finding anything relevant.
Thanks,
Andrei
--== Sent via Deja.com http://www.deja.com/ ==--
---Share what you know. Learn what you don't.---
[ 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: Philip Gibbs <philip.gibbs@weburbia.com>
Date: 1999/05/20 Raw View
In article <7hvum9$4bb$1@nnrp1.deja.com>, Andrei Alexandrescu
<andrewalex@hotmail.com> writes
>
>Let's analyze this code:
>
>class A
>{
> A();
>};
>
>class B : public A
>{
>public:
> B();
>};
>
>B::B()
>{
>}
>
>B var;
>
>The code is in error, because B's default constructor will implicitly
>call A's default constructor, which is private.
>
>The question is: when should the compiler generate an error? This is a
>no-nonsense question, please take it seriously.
>
>1. At B::B()'s declaration
>2. At B::B()'s definition
>3. At var's definition
2. I would expect it at B::B()'s definition because this
uses the private constructor A::A() which is illegal here.
>
>Is there any guarantee on *where* the error will be generated?
I don't think there even has to be a concept of where in the code
a compile time error is generated.
>Put another way: if you comment out var's definition, will the code be
>valid?
No, and with good reason. A similar variable declaration might
appear in another file where the definition of B::B() is not
included. Separate compilation would therefore be impossible
if the code was allowed to be valid.
>If not, and if you comment B::B's definition, will the code be
>valid?
Yes. The definition of B::B() could be in another source file
and could be valid if it used the copy constructor of A instead
of the default constructor. The copy constructor would have to
construct from an object of a class derived from A (e.g. B)
because objects
I know the following is useless but it is well formed
code giving an alternative definition of B::B() which will
produce no compile time error
B b;
B::B():
A(b)
{
}
I think the result must be undefined since b is constructed
using itself. I can't see a way of producing a definition
of B::B() which would not have undefined behaviour but it
would be a clever compiler which could deduce as much from
the class definitions.
[ 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: ebiederm@cse.unl.edu (Eric Biederman)
Date: 1995/07/08 Raw View
JdeBP@jba.co.uk (Jonathan de Boyne Pollard) writes:
>//
>// The following code does not compile on MetaWare High C++ 3.31a,
>// but compiles without error on Borland C++ 2.0 for OS/2, IBM
>// VisualAge C++ 3.00, EMX C++ 0.9a, and Watcom C++ 10.0b.
>//
>struct Base {
> void g() ;
>protected:
> void f() {}
>} ;
>struct Derived: public Base { } ;
>void
>Base::g ()
>{
> Derived d ;
> d.f() ;
>}
By reading Section 11 of the ARM here is what I come up with.
beginquotes
11
protected; that is , its name can be used only by member function,
member initializers, and friends of the class in which it is declared and
by member function and friends of classes derived from this class.
11.2
If a class is declared to be a base class for another class using the public
access specifier, the public members of the base class are public members
of the derived class and protected members of the base class are protected
members of the derived class. ...
11.5
A friend or a member function of a derived class can access a protected
static member of a base class. A friend or a member function of a derived
class can access a protected nonstatic member of one of it's base classes
only through a pointer to, reference to, or object of the derived class
(or any class derived from that class).
10
Unless redefiend in the derived class, members of a base class can be
referred to as if they were members of the derived class. The base class
members are said to be inherited by the derived class. The scope resolution
operator :: may be used to refuer to a base member explicitly. This allows
access to a name that has been redefined in the derived class. A derieved
class can itself serve as a basse class subject to access control; see 11.2
A poiner to a derieved class may be implicitly converted to a pointer to
an accessible unambiguous base class 4.6 A reference to a derivedd class
may be implicitly converted to a reverence to an unambiguous base class.
For example,
class base {
public:
int a, b;
};
class derived : public base {
public:
int b, c;
};
void f()
{
derived d;
d.a = 1;
d.base::b = 2;
d.b = 3;
d.c = 4;
base * bp = &d; // standard conversion:
// derived * to base *
}
assigns to the four members of d and makes bp point to d.
endquote
The question then remains are a, b also members of base while simultaneously
being members of the derived. I would say that they are.
If this is the case then the quotes that are present should be enough to
say the the error message is _wrong_ and that f is accessible as it is
a base class member. Being called from the base class.
Also 11.5 states clearly that a member function of a derived class can
access a protected member from the derived class or a class derived class.
Disallowing the other situation be an inconsistent handling of the situation.
I suspect the reason for the confusion is that most of the examples are
geared in the other direction, from derived to base.
Also the implied conversion of references from a derived to a base should
also handle the situation.
Unfortunantely I could not find this _explicitly_ stated in a completely
unambigous form. I am unexperience at reading standards to find these things
though so please forgive this newbie for imperfection.
>// By my reading of Chapter 11 of the WP, MetaWare is right and the
>// others wrong. The only way to achieve the desired result should be
>// to cast `d' to `Base &' before attempting the member access.
>//
>// Comments please.
Please comment on my comments and show me where you disagree.
Author: JdeBP@jba.co.uk (Jonathan de Boyne Pollard)
Date: 1995/07/08 Raw View
Eric Biederman (ebiederm@cse.unl.edu) wrote:
: JdeBP@jba.co.uk (Jonathan de Boyne Pollard) writes:
: >//
: >// The following code does not compile on MetaWare High C++ 3.31a,
: >// but compiles without error on Borland C++ 2.0 for OS/2, IBM
: >// VisualAge C++ 3.00, EMX C++ 0.9a, and Watcom C++ 10.0b.
: >//
: >
: >struct Base {
: > void g() ;
: >protected:
: > void f() {}
: >} ;
: >
: >struct Derived: public Base { } ;
: >
: >void
: >Base::g ()
: >{
: > Derived d ;
: > d.f() ;
: >}
:
: By reading Section 11 of the ARM here is what I come up with.
I was reading chapter 11 of the working paper. It's slightly different to
the ARM. You'll note, specifically, that 11.2 has changed. Whereas the
ARM says
: 11.2
: If a class is declared to be a base class for another class using the public
: access specifier, the public members of the base class are public members
: of the derived class and protected members of the base class are protected
: members of the derived class. ...
the working paper says
: 11.2
: If a class is declared to be a base class for another class (_class.derived_)
: using the public access specifier, the public members of the base class are
: accessible as public members of the derived class and protected members of
: the base class are accessible as protected members of the derived class. ...
which is not (to my mind) a gratuitous change. There must be some intent
here, and it seems that the intent is to clear up the confusion about
membership. It seems that inheritance doesn't cause actual transference of
membership from base to derived, but instead allows access to base members
as if they were members of derived (i.e. using the same syntax).
: >// By my reading of Chapter 11 of the WP, MetaWare is right and the
: >// others wrong. The only way to achieve the desired result should be
: >// to cast `d' to `Base &' before attempting the member access.
: >//
: >// Comments please.
: Please comment on my comments and show me where you disagree.
All right. Here goes.
: The question then remains are a, b [in the example in Chapter 10 of the
: ARM] also members of base while simultaneously being members of the derived.
: I would say that they are.
:
: If this is the case then the quotes that are present should be enough to
: say the the error message is _wrong_ and that f is accessible as it is
: a base class member. Being called from the base class.
I disagree partly because members are only members of the class they are
declared in, and membership is not transferred, and partly because of the
wording in the working paper :
11.5 Protected Member Access [class.protected]
2 A friend or a member function of a derived class can access a protected
nonstatic member of a base class. Except when forming a pointer to
member (_expr.unary.op_), the access must be through a pointer to,
reference to, or object of the derived class itself (or any class derived
from that class) (_expr.ref_). [...]
Which is very similar to the verse from the ARM that you quoted.
In my original example, the object *is* an object of the derived class, so
the second part of the verse is satisfied. Unfortunately, the first
part is *not* satisfied, since the function that is attempting the access
is *not* a friend or member of the derived class. It is a member of the
*base* class.
In other words, it seems to be the intention that whilst the implicit
Derived->Base conversion on `this' allows access to protected members of
Base in members of Derived, there is *no* implicit Derived->Base
conversion on instances of Derived when we are not in the class scope of
Derived.
Another argument for agreeing with the minority of C++ compilers is that if
Base::g() were a non-member function, we would expect the error message as
a matter of course, since non-member functions have only public access to
members of Derived and to public members of its public base classes, which
category clearly does not include Base::f(), it being a protected member.
I think that [class.protected] is very clear on protected access, and
(rightly or wrongly) restricts it specifically to access to protected
members of base classes when in the class scope of derived classes.
This seems pretty clear cut to me, and what amazed me initially was that my
first reaction (when I first encountered this) that "the majority is right"
was, in fact, wrong upon close reading of the language specification.
About the only quibble that I can see is the one that you brought up at the
end of your message, which is that the instance of Derived may be implicitly
converted to a reference to Base, allowing the function member of Base to
access the protected member of that instance. I agreed in my original
message that if the conversion was *explicit* then this was all right (and
this is the "workaround" for the problem, of course), but I cannot find
anything to justify an *implicit* conversion.
The verse in Chapter 10 of the ARM that you quoted in support of an implicit
reference conversion has actually been tightened up in the working paper,
and now only talks about binding an lvalue of Derived to a reference to
Base, rather than implicit reference conversions from the one to the
other.
So although I'm grateful for your taking the time to argue this out with
me and I'm still open to being persuaded on the subject, you haven't yet
convinced me that the minority of C++ compilers (Hewlett-Packard and
MetaWare) is wrong and the majority (IBM, Borland, EMX, and Watcom) right on
this issue yet.
Author: ebiederm@cse.unl.edu (Eric Biederman)
Date: 1995/07/08 Raw View
JdeBP@jba.co.uk (Jonathan de Boyne Pollard) writes:
>Eric Biederman (ebiederm@cse.unl.edu) wrote:
>: JdeBP@jba.co.uk (Jonathan de Boyne Pollard) writes:
>: >//
>: >// The following code does not compile on MetaWare High C++ 3.31a,
>: >// but compiles without error on Borland C++ 2.0 for OS/2, IBM
>: >// VisualAge C++ 3.00, EMX C++ 0.9a, and Watcom C++ 10.0b.
>: >//
>: >struct Base {
>: > void g() ;
>: >protected:
>: > void f() {}
>: >} ;
>: >
>: >struct Derived: public Base { } ;
>: >
>: >void
>: >Base::g ()
>: >{
>: > Derived d ;
>: > d.f() ;
>: >}
>: >
>:
>: By reading Section 11 of the ARM here is what I come up with.
>I was reading chapter 11 of the working paper. It's slightly different to
>the ARM. You'll note, specifically, that 11.2 has changed. Whereas the
>ARM says
>: 11.2
>: If a class is declared to be a base class for another class using the public
>: access specifier, the public members of the base class are public members
>: of the derived class and protected members of the base class are protected
>: members of the derived class. ...
>the working paper says
>: 11.2
>:If a class is declared to be a base class for another class (_class.derived_)
>: using the public access specifier, the public members of the base class are
>: accessible as public members of the derived class and protected members of
>: the base class are accessible as protected members of the derived class. ...
>which is not (to my mind) a gratuitous change. There must be some intent
>here, and it seems that the intent is to clear up the confusion about
>membership. It seems that inheritance doesn't cause actual transference of
>membership from base to derived, but instead allows access to base members
>as if they were members of derived (i.e. using the same syntax).
Then, the protected members of the base class are accessible as protected
members of the derived class, but nowhere does is say they must be accssed
as members of the derived class, so they are still members of the base
class, and when another member of the base class uses them there is no reason
to consider them members of the derived class and they are accessible.
Yes, this is a minor change but to my mind clears things up.
>: >// By my reading of Chapter 11 of the WP, MetaWare is right and the
>: >// others wrong. The only way to achieve the desired result should be
>: >// to cast `d' to `Base &' before attempting the member access.
>: >//
>: >// Comments please.
>: Please comment on my comments and show me where you disagree.
If you continue to do so please let's continue this.
>All right. Here goes.
>: The question then remains are a, b [in the example in Chapter 10 of the
>: ARM] also members of base while simultaneously being members of the derived.
>: I would say that they are.
>:
>: If this is the case then the quotes that are present should be enough to
>: say the the error message is _wrong_ and that f is accessible as it is
>: a base class member. Being called from the base class.
>I disagree partly because members are only members of the class they are
>declared in, and membership is not transferred, and partly because of the
>wording in the working paper :
So, you disagree with the fact that Chapter 10 of the ARM calls
a, b declared in the base class, members of the derived class. (correct?)
The current WP supports this disagrement, but says they can be
accessed as members of the derived class. This is functionally
what I meant by being both members of the derived, and base class.
Yes the are functionally members of the derived class as the derived
class can access them as such. Yes also they are members of the base
class, needing no special changes.
What I finally said was that if they are considered members of the base
class, where they are declared (and they are) then the access rules
say that a member function can access the protected members of it's
own class.
I don't follow your disagreement.
>11.5 Protected Member Access [class.protected]
>2 A friend or a member function of a derived class can access a protected
> nonstatic member of a base class. Except when forming a pointer to
> member (_expr.unary.op_), the access must be through a pointer to,
> reference to, or object of the derived class itself (or any class derived
^^^^^^^^^^^^^^^^^^^^^
> from that class) (_expr.ref_). [...]
^^^^^^^^^^^^^^^^ This is very compelling, and the strongest reason I could
find in the ARM.
Consider this case.
struct Base {
protected:
void f() {}
} ;
struct Derived1: public Base {
void g() ;
} ;
struct Derived2: public Derived1 { } ;
void
Derived1::g () // g is a member of a derived class
{ // so it can acces a protected member of Base
Derived2 d ; // the access is through a an object derived from
d.f() ; // it's own class
} // legal by section 11.5
The best argument that I could come up with yesterday is that if
_this_ example is legal then it seems it is both the intent of
the standard that the other case be legal, and it would be
inconsistent if it was legal through one layer of derivation and
not legal directly.
I probably didn't say this clearly enough.
Try this code and if it doesn't work those compilers are _broken_,
as of the ARM. As what is states is the current version of the language.
They seem to be to me already.
>Which is very similar to the verse from the ARM that you quoted.
It still has what I though was so compelling.
>In my original example, the object *is* an object of the derived class, so
>the second part of the verse is satisfied. Unfortunately, the first
>part is *not* satisfied, since the function that is attempting the access
>is *not* a friend or member of the derived class. It is a member of the
>*base* class.
Correct I was doing a consistency argument.
>In other words, it seems to be the intention that whilst the implicit
>Derived->Base conversion on `this' allows access to protected members of
>Base in members of Derived, there is *no* implicit Derived->Base
>conversion on instances of Derived when we are not in the class scope of
>Derived.
Yes, well there should not be a _conversion_ as this would lose all of the
features of being derived, but it should be a conversion of consideration.
Which happens to be what a refference conversion is.
>Another argument for agreeing with the minority of C++ compilers is that if
>Base::g() were a non-member function, we would expect the error message as
>a matter of course, since non-member functions have only public access to
>members of Derived and to public members of its public base classes, which
>category clearly does not include Base::f(), it being a protected member.
Yes, but Base::g() does have access to it's own protected members, one
of which is Base::f(), even if it happens to be in a derived object.
>I think that [class.protected] is very clear on protected access, and
>(rightly or wrongly) restricts it specifically to access to protected
>members of base classes when in the class scope of derived classes.
>This seems pretty clear cut to me, and what amazed me initially was that my
>first reaction (when I first encountered this) that "the majority is right"
>was, in fact, wrong upon close reading of the language specification.
Well, I've got Turbo C++ 3.0 usually I can tell if a piece of code is correct
if it _doesn't_ _compile_. So these compiler tests with the current state
of the language to me are _meaningless_.
>About the only quibble that I can see is the one that you brought up at the
>end of your message, which is that the instance of Derived may be implicitly
>converted to a reference to Base, allowing the function member of Base to
>access the protected member of that instance. I agreed in my original
>message that if the conversion was *explicit* then this was all right (and
>this is the "workaround" for the problem, of course), but I cannot find
>anything to justify an *implicit* conversion.
>The verse in Chapter 10 of the ARM that you quoted in support of an implicit
>reference conversion has actually been tightened up in the working paper,
>and now only talks about binding an lvalue of Derived to a reference to
>Base, rather than implicit reference conversions from the one to the
>other.
Yes, well it was the best I could do with what I had, and also with the
way you were thinking. I beleive that no conversion is necessary to
access members of the base class, even if you are calling through the
derived class.
>So although I'm grateful for your taking the time to argue this out with
>me and I'm still open to being persuaded on the subject, you haven't yet
>convinced me that the minority of C++ compilers (Hewlett-Packard and
>MetaWare) is wrong and the majority (IBM, Borland, EMX, and Watcom) right on
>this issue yet.
Well your quotes of the WP have actually convinced me otherwise.
I always though following computers taught me precision in though but
maybe not.
A quick recap before I sign off.
It is clear that protected members of a base class, may be accessed as
protected members of a base class. It does not say they must.
It is clear that a member function may access protected members of it's
own class. I saw no restrictions given as to where these members may
appear.
Therefore if the protected members of the base class are accessed through
an object of a derived class, they are accessible in a member function
of the base class.
In fact you should be able to acces private members of the base class
through an object of a derived class, in a member function of the
base class.
For me the issue is settled. Thanks for the fun.
Though if you still disagree I may try to convince you otherwise.
Sincerly,
Eric Biederman
ebiederm@cse.unl.edu
Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1995/07/06 Raw View
In article adq@bmdhh222.bnr.ca, dbinder@bnr.ca (David Binderman) writes:
>
>cfront 3 likes it, and g++ 2.7.0 likes it. So using the compiler majority
>vote rule, its a bug in Metaware.
>
>Even if it isn't a bug in Metaware, n - 1 compilers like the code,
>so that code is de-facto legal.
Is this a joke? Did I miss a smiley somewhere? Or am I just too grouchy
today?
After all, this newsgroup is comp.STD.c++. We should refer to the C++
language definition, and not the behavior of selected compilers,
when discussing the correct interpretation of source code.
---
Steve Clamage, stephen.clamage@eng.sun.com
Author: dbinder@bnr.ca (David Binderman)
Date: 1995/07/06 Raw View
Jonathan de Boyne Pollard (JdeBP@jba.co.uk) wrote:
: //
: // The following code does not compile on MetaWare High C++ 3.31a,
: // but compiles without error on Borland C++ 2.0 for OS/2, IBM
: // VisualAge C++ 3.00, EMX C++ 0.9a, and Watcom C++ 10.0b.
: //
: // Comments please.
cfront 3 likes it, and g++ 2.7.0 likes it. So using the compiler majority
vote rule, its a bug in Metaware.
Even if it isn't a bug in Metaware, n - 1 compilers like the code,
so that code is de-facto legal.
Regards
David C Binderman MSc BSc dbinder@bnr.co.uk +44 1628 794 887
Object Oriented Design & Analysis with C++ since 1988
RIP Plato the fish
Author: JdeBP@jba.co.uk (Jonathan de Boyne Pollard)
Date: 1995/07/06 Raw View
David Binderman (dbinder@bnr.ca) wrote:
: Jonathan de Boyne Pollard (JdeBP@jba.co.uk) wrote:
: : //
: : // The following code does not compile on MetaWare High C++ 3.31a,
: : // but compiles without error on Borland C++ 2.0 for OS/2, IBM
: : // VisualAge C++ 3.00, EMX C++ 0.9a, and Watcom C++ 10.0b.
: : //
: :
: : // Comments please.
:
: cfront 3 likes it, and g++ 2.7.0 likes it. So using the compiler majority
: vote rule, its a bug in Metaware.
On the other hand (as I said in the original message) there's the fact that
reading Chapter 11 of the WP seems to indicate that MetaWare is right and
all of the others are wrong. Incidentally, some colleagues of mine tried
to compile it with an HP/UX C++ compiler and that too complained.
: Even if it isn't a bug in Metaware, n - 1 compilers like the code,
: so that code is de-facto legal.
de facto, maybe; but not de jure.
You certainly haven't put up a convincing case that my reading of Chapter
11 of the WP is somehow flawed, which is what I was hoping that someone
would do. I still think that the minority is correct and the majority
wrong in this case.
Author: JdeBP@jba.co.uk (Jonathan de Boyne Pollard)
Date: 1995/07/05 Raw View
//
// The following code does not compile on MetaWare High C++ 3.31a,
// but compiles without error on Borland C++ 2.0 for OS/2, IBM
// VisualAge C++ 3.00, EMX C++ 0.9a, and Watcom C++ 10.0b.
//
struct Base {
void g() ;
protected:
void f() {}
} ;
struct Derived: public Base { } ;
void
Base::g ()
{
Derived d ;
d.f() ;
}
// By my reading of Chapter 11 of the WP, MetaWare is right and the
// others wrong. The only way to achieve the desired result should be
// to cast `d' to `Base &' before attempting the member access.
//
// Comments please.
Author: gjditchf@plg.waterloo.edu (Glen Ditchfield)
Date: Wed, 3 Jun 1992 14:34:26 GMT Raw View
This code is based on an example in the Annotated Reference Manual, page 240.
class X {
private:
enum E1 {a1, b1};
public:
enum E2 {a2, b2};
};
void h(X* p) {
X::E2 e2;
int x2 = X::a2;
X::E1 e1; // Should be an error?
int x1 = X::a1;
}
The ARM says that the declaration of e1 is illegal, because E1 is private.
However, AT&T C++ 2.1.0, AT&T C++ 3.0.1, and g++ 2.1 all say that the
declaration is just fine. (The compilers and the ARM agree that the use of
X::a1 on the next line is illegal.)
Are the compilers wrong? Is this part of the ARM obsolete?
Author: bs@alice.att.com (Bjarne Stroustrup)
Date: 4 Jun 92 01:39:12 GMT Raw View
gjditchf@plg.waterloo.edu (Glen Ditchfield @ University of Waterloo) writes
> This code is based on an example in the Annotated Reference Manual, page 240.
class X {
private:
enum E1 {a1, b1};
public:
enum E2 {a2, b2};
};
void h(X* p) {
X::E2 e2;
int x2 = X::a2;
X::E1 e1; // Should be an error?
int x1 = X::a1;
}
> The ARM says that the declaration of e1 is illegal, because E1 is private.
> However, AT&T C++ 2.1.0, AT&T C++ 3.0.1, and g++ 2.1 all say that the
> declaration is just fine. (The compilers and the ARM agree that the use of
> X::a1 on the next line is illegal.)
> Are the compilers wrong? Is this part of the ARM obsolete?
The compilers are wrong. They haven't yet caught up to the ARM in this matter.