Topic: Should the compiler warn for pure virt


Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: 1998/06/12
Raw View
Valentin Bonnard <bonnardv@pratique.fr> writes:

>David Harmon wrote:
>
>> Doesn't this open an unnecessary hole in encapsulation?

Yes, good point.

>There are a number of holes in encapsulation, but you can't
>break encapsulation by accident.
>
>The purpose of encapsulation isn't absolute security.

True, but was Bjarne aware of the encapsulation hole, and if not,
would Bjarne have designed things this way if he had?

I think the idea of this design was to avoid forcing the user to invent
two names for what is basically the same operation, in cases where the
base class wants to provide a default, but still force the user to
explicitly choose whether to use that default or to do something
different.  However, it has definitely caused a lot of confusion over
the years, and once you consider the encapsulation hole, it does seem
like a bit of a hack.  I doubt if any future languages will copy this one.

--
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3        |     -- the last words of T. S. Garp.
---
[ 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: Oleg Zabluda <zabluda@math.psu.edu>
Date: 1998/06/14
Raw View
Fergus Henderson <fjh@cs.mu.OZ.AU> wrote:
: I think the idea of this design was to avoid forcing the user to invent
: two names for what is basically the same operation, in cases where the
: base class wants to provide a default, but still force the user to
: explicitly choose whether to use that default or to do something
: different.

In at least one case choosing another name is not an option --
pure virtual destructors.

: However, it has definitely caused a lot of confusion over
: the years, and once you consider the encapsulation hole, it does seem
: like a bit of a hack.  I doubt if any future languages will copy this one.

Could you elaborate? What encapsulation hole?

Oleg.
--
Life is a sexually transmitted, 100% lethal disease.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: AllanW@my-dejanews.com
Date: 1998/06/14
Raw View
In article <6lrmp7$rp9$1@mulga.cs.mu.OZ.AU>,
  fjh@cs.mu.OZ.AU (Fergus Henderson) wrote:
>
> Valentin Bonnard <bonnardv@pratique.fr> writes:
>
> >David Harmon wrote:
> >> Doesn't this open an unnecessary hole in encapsulation?
> Yes, good point.
>
> >There are a number of holes in encapsulation, but you can't
> >break encapsulation by accident.
> >The purpose of encapsulation isn't absolute security.
> True, but was Bjarne aware of the encapsulation hole, and if not,
> would Bjarne have designed things this way if he had?

Bjarne was very clear on this subject.  In 1990 he discussed this at
length in reference to a different "encapsulation hole," namely the
protected: access specifier.  (After all, if you have a class with a
protected member, you could derive a class that sets and returns it in
public member functions, thus destroying encapsulation. But that couldn't
happen accidentally -- the appropriate word is "fraud.")

Bjarne said (The Annotated C++ Reference Manual, May 1991, section 11.1c,
page 256):
       C++ does not attempt to provide the most detailed control of
    protection or to provide every conceivable mechanism for expressing
    every conceivable protection need.  Doing that would imply a
    complexity far greater than what is provided, which already gives
    an uncommon degree of expressiveness.
       A few basic principles pervade the system:
       [1] Protection is provided by compile-time mechanisms, against
           accident, not against fraud or explicit violation.
       [2] Access is granted by a class, not unilaterally taken.
       [3] Access control is done for *names* and does not depend on the
           type of what is named.
       [4] The unit of protection is the class, not the individual object.
       [5] Access is controlled, not visibility.

(Point [1] is the most relevant to this discussion.  I typed the oth>
<input type=

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/   Now offering spam-free web-based newsreading
---
[ 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: Oleg Zabluda <zabluda@math.psu.edu>
Date: 1998/06/15
Raw View
Oleg Zabluda <zabluda@math.psu.edu> wrote:
: Fergus Henderson <fjh@cs.mu.OZ.AU> wrote:

: : However, it has definitely caused a lot of confusion over
: : the years, and once you consider the encapsulation hole, it does seem
: : like a bit of a hack.  I doubt if any future languages will copy this one.

: Could you elaborate? What encapsulation hole?

Never mind.

Oleg.
--
Life is a sexually transmitted, 100% lethal disease.
---
[ 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: source@netcom.com (David Harmon)
Date: 1998/06/11
Raw View
On 26 May 98 23:30:38 GMT, clamage@Eng.Sun.COM (Steve Clamage) wrote:

>Secondy, a function declared pure virtual isn't called via the
>virtual function-call mechanism. (Attempting to call a pure virtual
>function via the virtual mechanism has undefined results. You cannot
>expect such code to have any particular result.) A pure virtual
>function having a body can be called only by using the qualified name.

Therefore the fact that a function defined with a body in this way might
have the same unqualified name appears to provides no advantage.  It
might as well have been named C::function_conceptually_related_to_foo()
instead of C::foo() and save us all the confusion of functions that
appear to be declared virtual, but never appear in a vtable.

Doesn't this open an unnecessary hole in encapsulation?  For any class
that defines a pure virtual function with no body, some rogue user could
define his own body and have unlimited access to private members?

Why didn't the language just prohibit it?


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1998/06/11
Raw View
David Harmon wrote:

> Doesn't this open an unnecessary hole in encapsulation?

There are a number of holes in encapsulation, but you can't
break encapsulation by accident.

The purpose of encapsulation isn't absolute security.

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://pages.pratique.fr/~bonnardv/


[ 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: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1998/05/26
Raw View
In article 1@news01.deltanet.com, "Phlip" <tegan@deltanet.com> writes:
>Paul Black wrote:
>
>>"ShivKumar G." <g.shivkumar@tek.COM> wrote back to front:
>>>
>>> Hi,
>>>     You can avoid the error by adding a dummy body to it. Here it goes.
>>>    virtual void foo()=0
>>>     {   }
>>> I assume it should not give any errors now.
>>
>>It won't. It's not valid syntax. Secondly, because the call is a
>>virtual call, it will produce a run time error even though a body
>>is defined. To call X::foo() you would have to say X::foo() - but
>>then that's not a virtual call.
>
>It will - it is valid syntax. You are allowed to give a pure virtual a body,
>and calling it accidently through a constructor will not produce a runtime
>error.

Sorry, you are incorrect on both counts.

First, the syntax
 virtual void foo() = 0 { }
is invalid. You can provide a body for a pure virtual function, but
you can do so only with a separate function definition:
 class C {
 public:
  virtual void foo() = 0; // pure virtual declaration
 };
 void C::foo() { } // definition of pure virtual function

Secondy, a function declared pure virtual isn't called via the
virtual function-call mechanism. (Attempting to call a pure virtual
function via the virtual mechanism has undefined results. You cannot
expect such code to have any particular result.) A pure virtual
function having a body can be called only by using the qualified name.
Example:

 C::C()
 {
  foo();    // error, does not call C::foo #1
  C::foo(); // ok, C::foo has a definition #2
 }
 void f(C* cp)
 {
  cp->foo();    // never calls C::foo      #3
  cp->C::foo(); // always calls C::foo     #4
 }

In #1, "this->" is implicit, using the virtual call mechanism.
Since C::foo is pure virtual, that function will not be called.
Since we are in a constructor, the object's type is C, and no
derived-class function can override the pure virtual. The code
is always wrong, and the compiler can tell you about it, or let
the error be detected at run time.

In #2 and #4, we call the function explicitly, not using the
virtual mechanism. If the function has a body, it gets called.
If not, you probably get a link-time error.

In #3, C::foo doesn't get called. If cp really points to a derived
class, the overriding version of foo gets called. If cp really
points to a C (which can happen only if f gets called from a C
constructor or destructor), you get a run-time error.

These have always been the rules in C++.

---
Steve Clamage, stephen.clamage@sun.com
---
[ 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              ]