On 02/14/2012 03:05 AM, Jonathan M Davis wrote:
On Tuesday, February 14, 2012 02:43:29 Timon Gehr wrote:
On 02/14/2012 02:16 AM, Jonathan M Davis wrote:

Well, not being able override what cannot be accesses is a quite basic
requirement of security. Private members cannot be overriden in a
different module.

Have you ever read up on NVI? That's how it's supposed to work. The whole idea
is to have derived classes override functions without being able to use them.
It makes it so that the public function is non-virtual and contains whatever
stuff you want to guarantee is called before or after the private function,
which is then virtual.

http://www.gotw.ca/publications/mill18.htm


That article uses C++. It is not really a fair comparison, because in D there is no way to explicitly declare a method "private virtual", and D's private is different from C++'s private, and C++ has a different sub-typing and inheritance model. I think there are different design trade-offs at play.

But I can make better sense of your point of view now: When I was talking about virtual I meant just a function that has an entry in a vtbl and is invoked virtually, while you probably had C++'s semantics in mind.


The whole idea of overriding private for NVI is to allow derived classes
to override the private function's implementation but not call it.

This is confusing method implementation with overriding. I just read the
relevant sections of TDPL:

"D fully supports NVI by providing _specific guarantees_ when
*interfaces* use access specifiers."

It is an explicit special case because private wouldn't have much of a
meaning for interfaces otherwise. This means private interface members
would not be hidden, they are special _already_.

The fact that TDPL talks about interfaces in specific could be a good argument
for _not_ making private virtual for classes. But regardless, as it stands,
_nothing_ which is private is hidden. So, there's nothing special going on
with interfaces and private, except that you can't override them to actually
do NVI, so they're kind of pointless.


The fact that they cannot be implemented in a class that implements the interface seems to be a [TDPL] bug.


If private becomes virtual, then the compiler loses the ability to
inline non-final private functions unlessit can guarantee that it's
dealing with that exact type, which it
usually can't do in the type's own member functions.

The optimisation works for all private class members. The issue is the
virtual table layout for separate compilation with .di files, therefore
it is not a good idea to make private methods virtual. But that is not
required to satisfy TDPL anyway:

As far as I can see TDPL only requires private *interface* members to be
implementable. That is not a problem at all, interface vtbls use
thunking anyway. Therefore the private members could just be plugged
there and be called virtually through base interface calls and
non-virtually otherwise.

The optimization only works as long as the compiler can guarantee that no
derived classes override the private functions, since it doesn't necessarily
know about all of the derived classes.

The optimization works under the precondition that derived classes from a different module cannot override private member functions.

If D allowed NVI with classes the way that C++ does by making private virtual, 
then derived classes would _have_ to
be able to override private functions in base classes which are in separate
modules; they might even be in separate libraries. And then the compiler could
not guarantee that no derived classes overrode the private functions, and the
optimization could not be made. Hence why I'm arguing against making private
functions virtual.


Here you probably mean virtual as in C++. I agree.

Personally, I'd very much like to see access level affect visibility, but
Walter must be convinced.


I think there were some issues with overload sets, but I think overloads with differing accessibility should just be disallowed.



Reply via email to