Topic: Q: private inheritance and ambigious names
Author: Stefan Rupp <st.rupp@t-online.de>
Date: 2000/08/15 Raw View
Hi,
Bill Wade schrieb:
> if(dynamic_cast<Something*>(pBase) != NULL)
> DoSomethingBroken();
>
> Here the runtime behavior depends (in part) on the accessibility of both
> Base and Something within derived classes pointed at by pBase (5.2.7p8).
Sorry, but I don't understand what you are saying. Could you please
elaborate?
Doei,
struppi
---
[ 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: "Bill Wade" <billwade@wt.net>
Date: 2000/08/16 Raw View
"Stefan Rupp" <st.rupp@t-online.de> wrote
> Bill Wade schrieb:
> > if(dynamic_cast<Something*>(pBase) != NULL)
> > DoSomethingBroken();
> >
> > Here the runtime behavior depends (in part) on the accessibility of both
> > Base and Something within derived classes pointed at by pBase (5.2.7p8).
>
> Sorry, but I don't understand what you are saying. Could you please
> elaborate?
Sure. First a little background. I was responding to James Dennett, who
wrote
> are _any_
> situations where changing private/protected to public breaks
> otherwise legal code?
The usual answer to JD's question is no, and the example given looks
something like:
int i; // global
class base { int i; };
class derived: base
{
void foo(){ i = 7; }
}
This code is illegal. The 'i' in foo refers to base::i, and derived doesn't
have access to it. Some people have argued that the code should be legal,
and the 'i' in foo would refer to ::i. If that were the language rule you
could break (change the behaviour of) code by making b::i public. This is
not a problem with the current language. derived::foo isn't legal and is in
no danger of becoming broken.
Now on to the "unusual" example which gives a "yes" answer to JD's question.
struct Base { virtual ~Base(); };
struct Something { virtual ~Something(); };
class Derived: public Base, private Something{};
void foo()
{
Derived d;
Base* pBase = &d;
if(dynamic_cast<Something*>(pBase) != NULL)
DoSomethingBroken();
}
This code is legal (mod typos, assuming a suitable declaration for
DoSomethingBroken). It would also be legal if Something were a public base
of Derived. However changing "private" to "public" changes the behavior of
the program. Under most conditions dynamic cast can't "find" a base class
which isn't a public base of Derived. If Something is private, the dynamic
cast fails (returns a null pointer, however the program is still legal). If
Something is changed to be a public base of Derived the dynamic cast
succeeds, changing (breaking in this case) the behavior of the legal
program.
HTH
---
[ 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: James Dennett <james@sessami.com>
Date: 2000/08/16 Raw View
--------------6394D767C87B57E69F915C8A
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Bill Wade wrote:
> "James Dennett" <james@jamesd.demon.co.uk> wrote
>
> > Maybe one of our resident gurus can tell us whether there are _any_
> > situations where changing private/protected to public breaks otherwise
> legal
> > code?
>
> You can make contrived examples
>
> if(dynamic_cast<Base*>(pDerived) != NULL)
> DoSomethingBroken();
Thankyou for that example, which shows me that my question was not quite the one I meant to ask. I'm not sure quite how to phrase the question I really wanted to ask, but it's something more like: Can we find any code where changing private/protected to
public requires a translation-time diagnostic? In other words, code where
if (false) {
// mystery code here
}
compiles, but fails to compile when we change private/protected to public? I'm hoping that the answer is no, because the only effect of access control _at translation time_ is to check whether otherwise legal constructs are disallowed because of access
restrictions. Ideally, I'd like a reference into the Standard to back up any assertions, but any clues in the right direction would be appreciated.
A related question would be whether the private/protected to public transformation can have any defined effect on runtime behaviour except through dynamic_cast.
-- James Dennett <jdennett@acm.org>
--
Sessami is a trademark of Escape Velocity Technology Mobile Services Limited.
All information contained in this e-mail is confidential and for the use of
the addressee only. If you receive this message in error please notify.
--------------6394D767C87B57E69F915C8A
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: 7bit
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
Bill Wade wrote:
<blockquote TYPE=CITE>"James Dennett" <james@jamesd.demon.co.uk> wrote
<p>> Maybe one of our resident gurus can tell us whether there are _any_
<br>> situations where changing private/protected to public breaks otherwise
<br>legal
<br>> code?
<p>You can make contrived examples
<p> if(dynamic_cast<Base*>(pDerived) != NULL)
<br> DoSomethingBroken();</blockquote>
Thankyou for that example, which shows me that my question was not quite
the one I meant to ask. I'm not sure quite how to phrase the
question I really wanted to ask, but it's something more like: Can
we find any code where changing private/protected to public requires a
translation-time diagnostic? In other words, code where
<p>if (false) {
<br> // mystery code here
<br>}
<p>compiles, but fails to compile when we change private/protected to public?
I'm hoping that the answer is no, because the only effect of access control
_at translation time_ is to check whether otherwise legal constructs are
disallowed because of access restrictions. Ideally, I'd like a reference
into the Standard to back up any assertions, but any clues in the right
direction would be appreciated.
<p>A related question would be whether the private/protected to public
transformation can have any defined effect on runtime behaviour except
through dynamic_cast.
<p>-- James Dennett <jdennett@acm.org>
<pre>--
Sessami is a trademark of Escape Velocity Technology Mobile Services Limited.
All information contained in this e-mail is confidential and for the use of
the addressee only. If you receive this message in error please notify.</pre>
</html>
--------------6394D767C87B57E69F915C8A--
---
[ 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: brangdon@cix.compulink.co.uk
Date: 2000/08/17 Raw View
In article <8mq3vp$14m$1@news.online.de>, sebmol@gmx.net (Sebastian
Moleski) wrote:
> If you want to find out about the rationale behind this design
> decision, have a look at the ARM, Chapter 11, first and second
> section.
See also D&E $2.10, which was published after the ARM and which makes it
seem less clear-cut. Stroustrup writes:
I do wonder if this aspect of the C++ definition is the result
of a genuine design decision. It could simply be a default
outcome of the preprocessor technology used to implement
C with Classes that didn't get reviewed when C++ was implemented
with more appropriate compiler technology.
(In my view it is a bad rule, because it makes "private" less private.)
Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
brangdon@cix.co.uk | And close your eyes with holy dread,
| For he on honey dew hath fed
http://www.bhresearch.co.uk/ | And drunk the milk of Paradise."
---
[ 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: "Bill Wade" <bill.wade@stoner.com>
Date: 2000/08/18 Raw View
"James Dennett" <james@jamesd.demon.co.uk> wrote
> Can we find any code where changing private/protected to public requires a
> translation-time diagnostic?
I don't believe so. It certainly looks like the intent and wording of the
standard is that a compile-time construct that is invalid without
consideration of access control cannot become valid once access control is
considered.
I'm pretty sure you can make an example that gives you a compile time error
with the preprocessor, but that is a bit outside the box:
#define foo x##private
int foo;
float xpublic;
Changing private to public causes a compile time error. Although it isn't
legal to redefine a keyword, I think it is legal to paste onto a keyword as
shown.
> I'm hoping that the answer is no, because the only effect of access
control _at translation
> time_ is to check whether otherwise legal constructs are disallowed
because of access
> restrictions. Ideally, I'd like a reference into the Standard to back up
any assertions
I read the last two sentences fo 11p4 (not 11.4) as backing up your
assertion.
> A related question would be whether the private/protected to public
transformation can
> have any defined effect on runtime behavior except through dynamic_cast.
I believe that changing access from private to public can change runtime
behavior from "unspecified" to "defined" by changing a non-POD class to a
POD class.
struct bar
{
bool test(){ return ((char*)this) == &c; }
private:
char c;
};
If you change private to public then bar is POD, and the rules (9.2p17)
require test() to return true. As long as bar is not a POD (which is the
case as written), nothing in the standard requires test() to return true.
Does anyone know of existing compilers that actually re-order public/private
sections of a class for space or access optimizations?
---
[ 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: Stefan Rupp <st.rupp@t-online.de>
Date: 2000/08/11 Raw View
Hi!
Bill Wade schrieb:
> if(dynamic_cast<Base*>(pDerived) != NULL)
> DoSomethingBroken();
At lest g++ 2.95.2 rejects this, if Base is a private base class
of Derived.
Doei,
struppi
---
[ 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: "Bill Wade" <bill.wade@stoner.com>
Date: 2000/08/11 Raw View
"Stefan Rupp" <st.rupp@t-online.de> wrote in message
news:39943418.D1E51CE2@t-online.de...
> Hi!
>
> Bill Wade schrieb:
> > if(dynamic_cast<Base*>(pDerived) != NULL)
> > DoSomethingBroken();
>
> At lest g++ 2.95.2 rejects this, if Base is a private base class
> of Derived.
You and g++ are correct. My example violates a "shall" (5.2.7p5). Change
my example to
if(dynamic_cast<Something*>(pBase) != NULL)
DoSomethingBroken();
Here the runtime behavior depends (in part) on the accessibility of both
Base and Something within derived classes pointed at by pBase (5.2.7p8).
---
[ 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: Stefan Rupp <st.rupp@t-online.de>
Date: 2000/08/09 Raw View
Barry Margolin schrieb:
> Accessibility is only checked *after* a name is resolved to a specific
> class.
Why?
Regards,
Stefan
---
[ 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: "Bill Wade" <billwade@wt.net>
Date: 2000/08/10 Raw View
"James Dennett" <james@jamesd.demon.co.uk> wrote
> Maybe one of our resident gurus can tell us whether there are _any_
> situations where changing private/protected to public breaks otherwise
legal
> code?
You can make contrived examples
if(dynamic_cast<Base*>(pDerived) != NULL)
DoSomethingBroken();
---
[ 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: James Dennett <james@jamesd.demon.co.uk>
Date: 2000/08/08 Raw View
Stefan Rupp wrote:
> struct A {
> void foo();
> };
>
> struct A1 : private A {
> };
>
> struct B {
> };
>
> struct B1 : public B {
> };
>
> struct C : public A1, public B1 {
> void bar() { foo(); } // ERROR: ambigious
> };
>
> Why is the call to foo() from within C ambigious? Only one foo()
> method - B1::B::foo() - may be called, because the other one is
> not accessible from within the context of C, since A1 is derived
> private from A.
>
> Is this just a bug in the GCC (2.95.2) implementation or is this
> behaviour conforming to the ISO standard? I, certainly, don't
> like it at all! :-/
>
Name lookup comes before access is checked. If you want to check for
ambiguity, you can mentally replace all occurrences of "private" and
"protected" with "public" -- if your code is ambiguous, changing public back
to private won't help you. I believe that gcc does the right thing here.
Maybe one of our resident gurus can tell us whether there are _any_
situations where changing private/protected to public breaks otherwise legal
code?
-- James Dennett <jdennett@acm.org>
---
[ 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: llewelly.@@edevnull.dot.com
Date: 2000/08/08 Raw View
Stefan Rupp <st.rupp@t-online.de> writes:
> Good evening,
>
> please take a look at the following piece of code:
>
> struct A {
> void foo();
> };
>
> struct A1 : private A {
> };
private inheritance means that nothing in A is accessible to classes
(like C) derived from A1 .
>
> struct B {
> };
>
> struct B1 : public B {
> };
>
> struct C : public A1, public B1 {
> void bar() { foo(); } // ERROR: ambigious
> };
>
> Why is the call to foo() from within C ambigious? Only one foo()
> method - B1::B::foo() - may be called, because the other one is
> not accessible from within the context of C, since A1 is derived
> private from A.
>
> Is this just a bug in the GCC (2.95.2) implementation or is this
> behaviour conforming to the ISO standard? I, certainly, don't
> like it at all! :-/
>
Actually, gcc says that foo() is inaccessible -- *not*
ambigous. (Note: the actual text of a diagnostic is entirely a
QoI issume.)
{~/cc_exer}gcc -v
Reading specs from /usr/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/specs
gcc version 2.95.2 19991024 (release)
{~/cc_exer}g++ -g -Wall private_mi.cc
private_mi.cc: In method `void C::bar()':
private_mi.cc:2: `void A::foo()' is inaccessible
private_mi.cc:15: within this context
---
[ 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: 2000/08/08 Raw View
In article <398F1D16.65821DAB@t-online.de>, Stefan Rupp <st.rupp@t-
online.de> writes
>Why is the call to foo() from within C ambigious? Only one foo()
>method - B1::B::foo() - may be called, because the other one is
>not accessible from within the context of C, since A1 is derived
>private from A.
Access constraints do not hide names, only prevent their use if they are
eventually selected as a best match. IOWs access is not checked until
the selection has been made.
Francis Glassborow 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: Stefan Rupp <st.rupp@t-online.de>
Date: 2000/08/09 Raw View
Good afternoon,
Stefan Rupp schrieb:
> struct A {
> void foo();
> };
>
> struct A1 : private A {
> };
>
> struct B {
> };
>
> struct B1 : public B {
> };
>
> struct C : public A1, public B1 {
> void bar() { foo(); } // ERROR: ambigious
> };
Argh, sorry, I forgot something: struct B should have been declared
like this:
struct B {
void foo();
};
Otherwise there wouldn't be any name clash.
Regards,
Stefan
---
[ 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: "Sebastian Moleski" <sebmol@gmx.net>
Date: 2000/08/09 Raw View
"James Dennett" <james@jamesd.demon.co.uk>:
| Stefan Rupp wrote:
...
| Maybe one of our resident gurus can tell us whether there are _any_
| situations where changing private/protected to public breaks otherwise legal
| code?
Nowhere. It is not supposed to. If you want to find out about the rationale
behind this design decision, have a look at the ARM, Chapter 11, first and
second section. Although the ARM is not a standard, it explains some design
decisions in C++ made throughout the years quite well.
--
Sebastian Moleski
SurakWare Corp.
www.surakware.com (IE5 required)
---
[ 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: Stefan Rupp <st.rupp@t-online.de>
Date: 2000/08/07 Raw View
Good evening,
please take a look at the following piece of code:
struct A {
void foo();
};
struct A1 : private A {
};
struct B {
};
struct B1 : public B {
};
struct C : public A1, public B1 {
void bar() { foo(); } // ERROR: ambigious
};
Why is the call to foo() from within C ambigious? Only one foo()
method - B1::B::foo() - may be called, because the other one is
not accessible from within the context of C, since A1 is derived
private from A.
Is this just a bug in the GCC (2.95.2) implementation or is this
behaviour conforming to the ISO standard? I, certainly, don't
like it at all! :-/
Regards,
struppi
---
[ 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: Barry Margolin <barmar@genuity.net>
Date: 2000/08/07 Raw View
In article <398F1D16.65821DAB@t-online.de>,
Stefan Rupp <st.rupp@t-online.de> wrote:
>Why is the call to foo() from within C ambigious? Only one foo()
>method - B1::B::foo() - may be called, because the other one is
>not accessible from within the context of C, since A1 is derived
>private from A.
Accessibility is only checked *after* a name is resolved to a specific
class.
--
Barry Margolin, barmar@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
---
[ 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 ]