Thread View: comp.std.c++
9 messages
9 total messages
Started by Bill Duttweiler
Tue, 19 Mar 1991 16:53
protected != public-to-derived
Author: Bill Duttweiler
Date: Tue, 19 Mar 1991 16:53
Date: Tue, 19 Mar 1991 16:53
42 lines
1619 bytes
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
Author: David S. Masterson
Date: Fri, 22 Mar 1991 22:54
Date: Fri, 22 Mar 1991 22:54
25 lines
1700 bytes
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
Author: Scott Layson
Date: Sun, 24 Mar 1991 01:04
Date: Sun, 24 Mar 1991 01:04
55 lines
2341 bytes
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
Author: Dave Scidmore
Date: Sun, 24 Mar 1991 07:02
Date: Sun, 24 Mar 1991 07:02
80 lines
4922 bytes
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
Author: William M Miller
Date: Sun, 24 Mar 1991 20:51
Date: Sun, 24 Mar 1991 20:51
28 lines
1948 bytes
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
Author: Scott Layson
Date: Mon, 25 Mar 1991 18:36
Date: Mon, 25 Mar 1991 18:36
47 lines
3071 bytes
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
Author: Dave Scidmore
Date: Tue, 26 Mar 1991 02:40
Date: Tue, 26 Mar 1991 02:40
73 lines
4609 bytes
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
Author: Jim ADCOCK
Date: Tue, 26 Mar 1991 19:48
Date: Tue, 26 Mar 1991 19:48
5 lines
654 bytes
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
Author: Scott Layson Burson
Date: Wed, 27 Mar 1991 08:36
Date: Wed, 27 Mar 1991 08:36
62 lines
3570 bytes
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