🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

9 total messages Started by Bill Duttweiler Tue, 19 Mar 1991 16:53
protected != public-to-derived
#958
Author: Bill Duttweiler
Date: Tue, 19 Mar 1991 16:53
42 lines
1619 bytes
I posted this to comp.lang.c++ a week ago, and haven't gotten any
feedback. Since I neglected to post to comp.std.c++, I thought I'd try
THAT before giving up on it...

Is it illegal to call a protected member function on an instance other
than 'this'? Consider the following simple example:

class A
{
public:
    A();
protected:
    void SetState();
};

class B : public A
{
public:
    B(A* a) { MyA = a; }
    void Foo() { MyA->SetState(); }
protected:
    A *MyA;
};

When run through g++ (1.37.1), I get the following error message:

test.cc: In method void B::Foo ():
test.cc:13: method `void A::SetState ()' is protected

When run through Sun C++ (based on cfront 2.0), I get

"test.cc", line 13: error:  B::Foo() cannot access A::SetState(): protected  member

So, these compilers agree. But I don't: B is publicly derived from A
and should have access to protected member functions from within its
own member functions. I can call SetState() on 'this', why not on
MyA???
-- 
William K. Duttweiler                   Schlumberger Austin Systems Center
(512) 331-3000                          PO Box 200015
wkd@asc.slb.com                         Austin, TX  78720-0015
Re: protected != public-to-derived
#961
Author: David S. Masterson
Date: Fri, 22 Mar 1991 22:54
25 lines
1700 bytes
>>>>> On 19 Mar 91 16:53:33 GMT, wkd@asc.slb.com (Bill Duttweiler) said:

Bill> Is it illegal to call a protected member function on an instance other
Bill> than 'this'? Consider the following simple example:

[...example deleted...]

Bill> So, these compilers agree. But I don't: B is publicly derived from A
Bill> and should have access to protected member functions from within its
Bill> own member functions. I can call SetState() on 'this', why not on
Bill> MyA???

This is a difficult question to answer in a short and sweet way.

So, lets turn it around.  Why should B have access to protected members of MyA
since MyA is not in the inheritance chain of B (as opposed to A which is)?
What differentiates this access from B attempting to access the protected
members of some object MyC when B does not derive from C?
--
====================================================================
David Masterson					Consilium, Inc.
(415) 691-6311					640 Clyde Ct.
uunet!cimshop!davidm				Mtn. View, CA  94043
====================================================================
"If someone thinks they know what I said, then I didn't say it!"
Re: protected != public-to-derived
#964
Author: Scott Layson
Date: Sun, 24 Mar 1991 01:04
55 lines
2341 bytes
In article <1991Mar19.165333.23908@asc.slb.com> wkd@asc.slb.com (Bill Duttweiler) writes:
>
>I posted this to comp.lang.c++ a week ago, and haven't gotten any
>feedback. Since I neglected to post to comp.std.c++, I thought I'd try
>THAT before giving up on it...
>
>Is it illegal to call a protected member function on an instance other
>than 'this'? Consider the following simple example:
>
>class A
>{
>public:
>    A();
>protected:
>    void SetState();
>};
>
>class B : public A
>{
>public:
>    B(A* a) { MyA = a; }
>    void Foo() { MyA->SetState(); }
>protected:
>    A *MyA;
>};
>
>When run through g++ (1.37.1), I get the following error message:
> [...]

The second sentence of section 11.5 of E&S (p. 253) reads:

   A friend or a a member function of a derived class can access a
   protected nonstatic member of one of its base classes only through
   a pointer to, reference to, or obejct of the derived class (or any
   class derived from that class).

I have bumped my head on this rule a couple of times, and frankly
don't agree with the rationale given in E&S for its existence (see the
commentary starting on the bottom of p.254).  The last sentence of
that rationale, which describes a bug someone once had which the rule
would have prevented, reads:

   Naturally, the use of a virtual function for performing the update
   would have avoided the problem.

Seems to me that this sentence admits that the bug really had quite
another cause than the mistaken access of a protected member.

Since the issue has come up, I am very much interested to hear the
committee's current feeling about this rule.  Unless that feeling
turns out to be one of utter attachment, I may consider submitting a
formal proposal and argument that it be rescinded (which would be a
compatible change, affecting no previously legal code).

-- Scott Layson Burson
Re: protected != public-to-derived
#978
Author: Dave Scidmore
Date: Sun, 24 Mar 1991 07:02
80 lines
4922 bytes
In article <1991Mar24.010442.27298@kestrel.edu> gyro@kestrel.edu (Scott Layson) writes:

>The second sentence of section 11.5 of E&S (p. 253) reads:
>
>   A friend or a a member function of a derived class can access a
>   protected nonstatic member of one of its base classes only through
>   a pointer to, reference to, or obejct of the derived class (or any
>   class derived from that class).
>
>I have bumped my head on this rule a couple of times, and frankly
>don't agree with the rationale given in E&S for its existence (see the
>commentary starting on the bottom of p.254).  The last sentence of
>that rationale, which describes a bug someone once had which the rule
>would have prevented, reads:
>
>   Naturally, the use of a virtual function for performing the update
>   would have avoided the problem.
>
>Seems to me that this sentence admits that the bug really had quite
>another cause than the mistaken access of a protected member.

I think you may be missing the point. The text which you neglected to
include stated:

    There are examples where the restriction appears to provide protection
    against accidents. For example suppose I am running a bank, and have
    many different kinds of accounts. I would like to have a base class
    "Account", that has information common to all kinds of accounts,
    including including the account balance, so a friend of "Account" can
    walk the list of all "Accounts" and tell me the financial position of
    my bank at any time. Each kind of "Account", however, has its own rules
    for updating the balance (for example, what rate of interest is paid,
    when it is compounded, what types of deposits are accepted, special
    penalties for early withdrawal, and so on), so the derived classes which
    are all the different kinds of accounts contain code for updating the
    balance. The member functions of "checking_accounts", however should
    not be able to access the balance in an "AutoLoan_account." The
    restriction prevents that.

It is hard to deny that a measure of protection has been afforded by the
restriction that some form of the derived object be used to access protected
base information. Any time accidents can be avoided by introducing a reasonable
protection mechanism I fail to see why someone would oppose it. Especially since
their is a way to bypass the protection, as stated on page 254 when talking
about easing the restriction:

    ...This would allow a class to access the base class part of an unrelated
    class (as if it were its own) without the use of an explicit cast.

So it can be seen that a cast can be used to bypass this rule. The second
grounds on which I feel the rule is reasonable is elequently stated just
after the above:

    ...without the use of an explicit cast. This would be the only place
    where the language allowed this.

In other words it is consistent with, and a logical extension of, existing
protection mechanisms. If you were big on logical consistency then you might
easily be fooled by the relaxation of this rule, expecting errors to be
generated if you attempted to use the wrong class to change protected base
class data. You might spend many days or even weeks hunting down such an
obscure and subtle error in a large program.

By contrast I am rarely fooled by compiler error messages. If I can not find
anything in the program to indicate a syntactical error my first impulse is
to grab a language reference and see if I am doing something wrong. Once I
find the mistake I made I rarely make it again. Ultimately, the whole process
may only take a few minutes to a few hours to eliminate the compilation
error. If, like the bug created by the relaxed rules, it takes days or weeks
for you to eliminate a compilation error that results form a less than full
understanding of the language, then you might consider a different line of
work. At the very least you would have trouble explaining it to your boss.

In other words I would rather spend a few minutes looking through E&S than
a few days hunting down an obscure bug. In that sense I think the protection
is worth the cost, especialy when I can bypass it and at the same time make
it quite clear that I intended to by using a cast.
--
Dave Scidmore, Heurikon Corp.
dave.scidmore@heurikon.com
Re: protected != public-to-derived
#965
Author: William M Miller
Date: Sun, 24 Mar 1991 20:51
28 lines
1948 bytes
gyro@kestrel.edu (Scott Layson) writes:
> I have bumped my head on this rule a couple of times, and frankly
> don't agree with the rationale given in E&S for its existence (see the
> commentary starting on the bottom of p.254).  The last sentence of
> that rationale, which describes a bug someone once had which the rule
> would have prevented, reads:
>
>    Naturally, the use of a virtual function for performing the update
>    would have avoided the problem.
>
> Seems to me that this sentence admits that the bug really had quite
> another cause than the mistaken access of a protected member.
>
> Since the issue has come up, I am very much interested to hear the
> committee's current feeling about this rule.

I can't speak for the rest of the committee, but I personally think the
rationale is pretty reasonable.  It might very well be that Derived1 and
Derived2 classes have different conventions for managing the protected
members of their common base class.  If a Derived1 member function were able
to access the base class protected members via a pointer or reference to the
base class, because of the conversion rules, it might actually be
manipulating a Derived2 object in an invalid fashion.  By restricting access
to use only a Derived1 pointer or reference, you at least have the type
system working in your favor to avoid this kind of bug.

-- William M. Miller, Glockenspiel, Ltd.; vice chair, X3J16
   wmm@world.std.com
Re: protected != public-to-derived
#972
Author: Scott Layson
Date: Mon, 25 Mar 1991 18:36
47 lines
3071 bytes
In article <1991Mar24.205156.10206@world.std.com> wmm@world.std.com (William M Miller) writes:
>gyro@kestrel.edu (Scott Layson) writes:
>> Since the issue has come up, I am very much interested to hear the
>> committee's current feeling about this rule.
>
>I can't speak for the rest of the committee, but I personally think the
>rationale is pretty reasonable.  It might very well be that Derived1 and
>Derived2 classes have different conventions for managing the protected
>members of their common base class.  If a Derived1 member function were able
>to access the base class protected members via a pointer or reference to the
>base class, because of the conversion rules, it might actually be
>manipulating a Derived2 object in an invalid fashion.  By restricting access
>to use only a Derived1 pointer or reference, you at least have the type
>system working in your favor to avoid this kind of bug.

Let's look at the example given at the top of p. 255 of E&S:

   For example, suppose I am running a bank, and I have many different
   kinds of accounts.  I would like to have a base class, `Account',
   that has information common to all kinds of accounts, including the
   account balance, so a friend of `Account' can walk the list of all
   Accounts and tell me the financial position of my bank at any time.
   Each kind of `Account', however, has its own rules for updating the
   balance ([examples omitted]), so the derived classes which are all
   the different kinds of accounts contain the code for updating the
   balance.  The member functions of checking_accounts, however,
   should not be able to access the balance in an `AutoLoan_account'.
   The restriction prevents that.

An easy way to implement this, in the absence of the restriction, is
that `Account' should not own the `balance' member variable, but that
`Account' should provide a private virtual function for retrieving the
balance.

Put another way, why do you want to make `balance' a member variable
of `Account' if you *don't* want the derived classes of `Account' to
be able to access each other's balance?

Since there's another way to achieve the protection you want, and
since the restriction is demonstrably counterintuitive to a lot of
people -- a) it contradicts the simple rule "protected = public-to-
derived" and b) it goes against the grain of "the unit of protection
is the class, not the object" (I'm not saying it literally contradicts
that philosophy, only that it seems to) -- I oppose it.

-- Scott Layson Burson
Gyro@Reasoning.COM
Re: protected != public-to-derived
#979
Author: Dave Scidmore
Date: Tue, 26 Mar 1991 02:40
73 lines
4609 bytes
gyro@kestrel.edu (Scott Layson) writes:
>wmm@world.std.com (William M Miller) writes:
>>gyro@kestrel.edu (Scott Layson) writes:
>>> Since the issue has come up, I am very much interested to hear the
>>> committee's current feeling about this rule.
>>
>>I can't speak for the rest of the committee, but I personally think the
>>rationale is pretty reasonable.
>
>Let's look at the example given at the top of p. 255 of E&S:
>
>   For example, suppose I am running a bank, and I have many different
>   kinds of accounts.  I would like to have a base class, `Account',
>   that has information common to all kinds of accounts, including the
>   account balance, so a friend of `Account' can walk the list of all
>   Accounts and tell me the financial position of my bank at any time.
>   Each kind of `Account', however, has its own rules for updating the
>   balance ([examples omitted]), so the derived classes which are all
>   the different kinds of accounts contain the code for updating the
>   balance.  The member functions of checking_accounts, however,
>   should not be able to access the balance in an `AutoLoan_account'.
>   The restriction prevents that.
>
>An easy way to implement this, in the absence of the restriction, is
>that `Account' should not own the `balance' member variable, but that
>`Account' should provide a private virtual function for retrieving the
>balance.

Again I think you are missing the point. The point is not whether you can
design your way around a hole in the protection mechanisms of the language,
but whether relaxation of this rule creates the possibility for programmer
error that need not exist. Using the above rational I could say that GOTOs
are a good idea because anyone using good programming practices won't require
them.

>Since there's another way to achieve the protection you want, and
>since the restriction is demonstrably counterintuitive to a lot of
>people -- a) it contradicts the simple rule "protected = public-to-
>derived"

Which would you rather have a rule that is counterintuitive or one that
is not logicaly consistent with the rest of the type checking system. I
think it is only counterintuitive to those that have not given it much
thought. One way of thinking about it that makes it more intuitive is to
think of those protected members who are accessed through the derived type
as conceptually belonging to that derived type.

The need to treat protected members of the base class this way stems from
the fact that protected members already represent a breach of the protection
mechanism. This breach is made for convience sake, but when combined with
implicit conversion of pointers to objects of a derived class to pointers
to objects of a public base class, you suddenly have the ability for
unrelated derived objects to get at each others data. The result is that
all the protections afforded by the class heirarchy go out the window for
protected data. The simple solution was the obvious one, since protected
data in essence is an extension of the private data of the derived type,
why not simply make the same rules apply to private data and protected
data inherited from a base class.

> b) it goes against the grain of "the unit of protection is the class,
> not the object" (I'm not saying it literally contradicts that philosophy,
> only that it seems to) -- I oppose it.

Huh? The rule does *nothing* in any way to shift the unit of protection from
that of the class to the object. Unless I am grossly mistaken *any* object
of the derived class can access protected base class data in any other object
of the same class. If anything this rule modifies the rule about converting
pointers to objects to pointers to one of their public base classes so that
the conversion can not be done in order to access protected data. To me this
seems completely logical and completely consistent.
--
Dave Scidmore, Heurikon Corp.
dave.scidmore@heurikon.com
Re: protected != public-to-derived
#983
Author: Jim ADCOCK
Date: Tue, 26 Mar 1991 19:48
5 lines
654 bytes
In article <1991Mar19.165333.23908@asc.slb.com> wkd@asc.slb.com (Bill Duttweiler) writes:
|Is it illegal to call a protected member function on an instance other
|than 'this'? 

See ARM section 11.5
Re: protected != public-to-derived
#985
Author: Scott Layson Burson
Date: Wed, 27 Mar 1991 08:36
62 lines
3570 bytes
In article <229@heurikon.heurikon.com> daves@ex.heurikon.com (Dave Scidmore) writes:
>[quote from E&S p. 255 deleted]
>
>It is hard to deny that a measure of protection has been afforded by the
>restriction that some form of the derived object be used to access protected
>base information. Any time accidents can be avoided by introducing a reasonable
>protection mechanism I fail to see why someone would oppose it. Especially since
>their is a way to bypass the protection, as stated on page 254 when talking
>about easing the restriction:
>
>    ...This would allow a class to access the base class part of an unrelated
>    class (as if it were its own) without the use of an explicit cast.
>
>So it can be seen that a cast can be used to bypass this rule.

Not in the presence of virtual base classes, which cannot be cast to a
derived class.  (I should have mentioned this before -- this is a
problem I actually encountered.)

But beyond that, in one application I found myself repeatedly
inserting such casts solely for the purpose of bypassing this rule.
(I can't defend myself if you say I must have been doing something
else wrong.  It was months ago and I don't remember all the details
about the situation.)  I will oppose even a reasonable-seeming
protection mechanism if I frequently have to bypass it with a cast,
because I believe that casts should only be used in exceptional
situations, lest people get too used to seeing them.

>							       The second
>grounds on which I feel the rule is reasonable is elequently stated just
>after the above:
>
>    ...without the use of an explicit cast. This would be the only place
>    where the language allowed this.
>
>In other words it is consistent with, and a logical extension of, existing
>protection mechanisms. If you were big on logical consistency then you might
>easily be fooled by the relaxation of this rule, expecting errors to be
>generated if you attempted to use the wrong class to change protected base
>class data. You might spend many days or even weeks hunting down such an
>obscure and subtle error in a large program.

Evidently that happened to someone, and that's why we have the rule.

See a previous posting of mine on the differences between friendship
and derivation.

>By contrast I am rarely fooled by compiler error messages. If I can not find
>anything in the program to indicate a syntactical error my first impulse is
>to grab a language reference and see if I am doing something wrong. Once I
>find the mistake I made I rarely make it again.

In general that's true for me too, but I am evidently not the only
person who had particular trouble finding this restriction given the
error messages I received from the compiler.  Perhaps if nothing else
comes of this conversation, at least compiler authors might be
persuaded to word as specifically as possible the error messages
generated on account of the restriction.  (Hello out there, are you
listening?)

-- Scott Layson Burson
Gyro@Reasoning.COM
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads