www.digitalmars.com         C & C++   DMDScript  

D - Function members (final and static attribs)

reply Dario <Dario_member pathlink.com> writes:
Private functions cannot be overridden so I presume
they are implicitly final, am I right?

I was wondering if the compiler can automatically decide
if a function can be static or not where it is not specified
in the code. Can it?

-Dario
Jul 12 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Dario" <Dario_member pathlink.com> wrote in message
news:bepojd$1v2o$1 digitaldaemon.com...
 Private functions cannot be overridden so I presume
 they are implicitly final, am I right?
Yes.
 I was wondering if the compiler can automatically decide
 if a function can be static or not where it is not specified
 in the code. Can it?
It could by looking at the function body and seeing if there are no references to 'this'. However, this will fail if someone uses an abstract declaration of the function (i.e. declares it without a body), so I'd say that no, the compiler can't do it.
Jul 22 2003
parent reply "Matthew Wilson" <matthew stlsoft.org> writes:
 I was wondering if the compiler can automatically decide
 if a function can be static or not where it is not specified
 in the code. Can it?
It could by looking at the function body and seeing if there are no references to 'this'. However, this will fail if someone uses an abstract declaration of the function (i.e. declares it without a body), so I'd say that no, the compiler can't do it.
Am firmly of the opinion that this would be a hideous thing conceptually, even if it were doable (which it is not). I am, however, intrigued, as to whether functions that don't use 'this' still make reference to it. In other words, will D support the safe-this idiom, use by MFC in GetSafeHwnd()? Specifically, can I write the following class X { public: bool is_null() { return null == this ? true : false; } } int main(. . .) { X x1 = new X(); X x2 = null; printf("x1: %s\n", x1.is_null() ? "null" : "non-null"); printf("x2: %s\n", x2.is_null() ? "null" : "non-null"); return 0; } and have it print non-null null rather than crash after printing non-null ?
Jul 23 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Matthew Wilson" <matthew stlsoft.org> wrote in message
news:bfnmkd$2uqa$1 digitaldaemon.com...
 I was wondering if the compiler can automatically decide
 if a function can be static or not where it is not specified
 in the code. Can it?
It could by looking at the function body and seeing if there are no references to 'this'. However, this will fail if someone uses an
abstract
 declaration of the function (i.e. declares it without a body), so I'd
say
 that no, the compiler can't do it.
Am firmly of the opinion that this would be a hideous thing conceptually, even if it were doable (which it is not). I am, however, intrigued, as to whether functions that don't use 'this' still make reference to it. In other words, will D support the safe-this idiom, use by MFC in GetSafeHwnd()? Specifically, can I write the
following
 class X
 {
 public:
     bool    is_null()
     {
         return null == this ? true : false;
     }
 }

 int main(. . .)
 {
     X    x1    =    new X();
     X    x2    =    null;

     printf("x1: %s\n", x1.is_null() ? "null" : "non-null");
     printf("x2: %s\n", x2.is_null() ? "null" : "non-null");

     return 0;
 }

 and have it print

         non-null
         null

 rather than crash after printing

         non-null

 ?
You can only use that idiom if is_null() is final, otherwise it will crash going through the vtbl[].
Aug 18 2003
parent reply "Matthew Wilson" <matthew stlsoft.org> writes:
"Walter" <walter digitalmars.com> wrote in message
news:bhre6s$1nmf$1 digitaldaemon.com...
 "Matthew Wilson" <matthew stlsoft.org> wrote in message
 news:bfnmkd$2uqa$1 digitaldaemon.com...
 I was wondering if the compiler can automatically decide
 if a function can be static or not where it is not specified
 in the code. Can it?
It could by looking at the function body and seeing if there are no references to 'this'. However, this will fail if someone uses an
abstract
 declaration of the function (i.e. declares it without a body), so I'd
say
 that no, the compiler can't do it.
Am firmly of the opinion that this would be a hideous thing
conceptually,
 even if it were doable (which it is not).

 I am, however, intrigued, as to whether functions that don't use 'this'
 still make reference to it. In other words, will D support the safe-this
 idiom, use by MFC in GetSafeHwnd()? Specifically, can I write the
following
 class X
 {
 public:
     bool    is_null()
     {
         return null == this ? true : false;
     }
 }

 int main(. . .)
 {
     X    x1    =    new X();
     X    x2    =    null;

     printf("x1: %s\n", x1.is_null() ? "null" : "non-null");
     printf("x2: %s\n", x2.is_null() ? "null" : "non-null");

     return 0;
 }

 and have it print

         non-null
         null

 rather than crash after printing

         non-null

 ?
You can only use that idiom if is_null() is final, otherwise it will crash going through the vtbl[].
Which brings us round to the possibilities of having a nonvirtual keyword and non-virtual methods, for those of us who feel the need. Maybe final is the way to go, but AFAIU final does not stipulate non-virtuality, just "no more overriding beyond this point".
Aug 18 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Matthew Wilson" <matthew stlsoft.org> wrote in message
news:bhrjhf$1vsd$1 digitaldaemon.com...
 You can only use that idiom if is_null() is final, otherwise it will
crash
 going through the vtbl[].
Which brings us round to the possibilities of having a nonvirtual keyword and non-virtual methods, for those of us who feel the need. Maybe final is the way to go, but AFAIU final does not stipulate non-virtuality, just "no more overriding beyond this point".
Final might as well stipulate non-virtuality, as there is no semantic difference between the two.
Aug 21 2003
parent reply "Mike Wynn" <mike.wynn l8night.co.uk> writes:
"Walter" <walter digitalmars.com> wrote in message
news:bi4dd3$2o0v$1 digitaldaemon.com...
 "Matthew Wilson" <matthew stlsoft.org> wrote in message
 news:bhrjhf$1vsd$1 digitaldaemon.com...
 You can only use that idiom if is_null() is final, otherwise it will
crash
 going through the vtbl[].
Which brings us round to the possibilities of having a nonvirtual
keyword
 and non-virtual methods, for those of us who feel the need. Maybe final
is
 the way to go, but AFAIU final does not stipulate non-virtuality, just
"no
 more overriding beyond this point".
Final might as well stipulate non-virtuality, as there is no semantic difference between the two.
only if not an overriden final or accessed via a pointer to the class where it is declared final or sub class there of class A { int foo() { return 1; } } class B : A { final int foo() { return 0; } } class C : B { final int bar() { return 0; } } int func( A a ) { return a.foo(); } // virtual call (must be) int func( B b ) { return b.foo(); } // can be nonvirtual int func( C b ) { return c.foo(); } // can be nonvirtual B::foo
Aug 22 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Mike Wynn" <mike.wynn l8night.co.uk> wrote in message
news:bi5bgf$13nv$5 digitaldaemon.com...
 "Walter" <walter digitalmars.com> wrote in message
 news:bi4dd3$2o0v$1 digitaldaemon.com...
 "Matthew Wilson" <matthew stlsoft.org> wrote in message
 news:bhrjhf$1vsd$1 digitaldaemon.com...
 You can only use that idiom if is_null() is final, otherwise it will
crash
 going through the vtbl[].
Which brings us round to the possibilities of having a nonvirtual
keyword
 and non-virtual methods, for those of us who feel the need. Maybe
final
 is
 the way to go, but AFAIU final does not stipulate non-virtuality, just
"no
 more overriding beyond this point".
Final might as well stipulate non-virtuality, as there is no semantic difference between the two.
only if not an overriden final or accessed via a pointer to the class
where
 it is declared final or sub class there of

 class A { int foo() { return 1; } }
 class B : A { final int foo() { return 0; } }
 class C : B { final int bar() { return 0; } }

 int func( A a ) { return a.foo(); } // virtual call (must be)
 int func( B b ) { return b.foo(); } // can be nonvirtual
 int func( C b ) { return c.foo(); } // can be nonvirtual  B::foo
Right. It is an error to override a final!
Aug 22 2003
parent reply "Mike Wynn" <mike.wynn l8night.co.uk> writes:
"Walter" <walter digitalmars.com> wrote in message
news:bi5l0r$1hih$1 digitaldaemon.com...
 "Mike Wynn" <mike.wynn l8night.co.uk> wrote in message
 news:bi5bgf$13nv$5 digitaldaemon.com...
 "Walter" <walter digitalmars.com> wrote in message
 news:bi4dd3$2o0v$1 digitaldaemon.com...
 "Matthew Wilson" <matthew stlsoft.org> wrote in message
 news:bhrjhf$1vsd$1 digitaldaemon.com...
 You can only use that idiom if is_null() is final, otherwise it
will
 crash
 going through the vtbl[].
Which brings us round to the possibilities of having a nonvirtual
keyword
 and non-virtual methods, for those of us who feel the need. Maybe
final
 is
 the way to go, but AFAIU final does not stipulate non-virtuality,
just
 "no
 more overriding beyond this point".
Final might as well stipulate non-virtuality, as there is no semantic difference between the two.
only if not an overriden final or accessed via a pointer to the class
where
 it is declared final or sub class there of

 class A { int foo() { return 1; } }
 class B : A { final int foo() { return 0; } }
 class C : B { final int bar() { return 0; } }

 int func( A a ) { return a.foo(); } // virtual call (must be)
 int func( B b ) { return b.foo(); } // can be nonvirtual
 int func( C b ) { return c.foo(); } // can be nonvirtual  B::foo
Right. It is an error to override a final!
I have not overriden a final [the code was a little wrong] should be class A { int foo() { return 1; } } class B : A { final int foo() { return 0; } } class C : B { final int bar() { return 0; } } int func( A a ) { return a.foo(); } // virtual call (must be) int func( B b ) { return b.foo(); } // can be nonvirtual int func( C c ) { return c.foo(); } // can be nonvirtual B::foo int main( char[][] args ) { A a = new A(); B b = new B(); C c = new C(); func ( a ); func(b); func(c); return 0; } still func(A a ) need to make a virtual call to foo foo is declared `virtual` in A then `final` in B do you mean an overridden function can not be final ? (the above code compiles) the above code compiles fine and runs and as the other test implies you are making a virtual call to a final function. so final and `non-virtual` are not the same always. class A { int foo() { return 1; } } class B : A { final int foo() { return 0; } } class C : B { final int bar() { return 0; } } int funcA( A a ) { return a.foo(); } // virtual call (must be) int funcB( B b ) { return b.foo(); } // can be nonvirtual int main( char[][] args ) { A a = new A(); B b = new B(); C c = new C(); int i; i = funcA( a ); printf( "funcA(a) = %d\n", i ); i = funcA( b ); printf( "funcA(b) = %d\n", i ); i = funcA( c ); printf( "funcA(c) = %d\n", i ); i = funcB( b ); printf( "funcB(b) = %d\n", i ); i = funcB( c ); printf( "funcB(c) = %d\n", i ); return 0; } outputs funcA(a) = 1 funcA(b) = 0 funcA(c) = 0 funcB(b) = 0 funcB(c) = 0 as you would expect
Aug 22 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Mike Wynn" <mike.wynn l8night.co.uk> wrote in message
news:bi6hdd$2rpa$3 digitaldaemon.com...
 Right. It is an error to override a final!
I have not overriden a final [the code was a little wrong]
Correct, you did not. If you did, the compiler should have issued an error.
Aug 22 2003
parent reply "Mike Wynn" <mike.wynn l8night.co.uk> writes:
"Walter" <walter digitalmars.com> wrote in message
news:bi6uhq$f05$1 digitaldaemon.com...
 "Mike Wynn" <mike.wynn l8night.co.uk> wrote in message
 news:bi6hdd$2rpa$3 digitaldaemon.com...
 Right. It is an error to override a final!
I have not overriden a final [the code was a little wrong]
Correct, you did not. If you did, the compiler should have issued an
error.

but still you said `final` and non-virtual are the same.
but they are not quite, a final functions might have a vtbl entry (but will
never create a new one)
and a final function may be entered via the vtbl it is not always called
directly.
I accept that from the class where it is declared final and evokes can be
non-virtual but it does not break D semantics to always evoke member
functions via the vtbl.
you have chosen to optimise the final calls when you can (statically does
what Java Jit do).
or is that optimisation part of the D semantic spec ?
Aug 23 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Mike Wynn" <mike.wynn l8night.co.uk> wrote in message
news:bi8aa9$2m7h$1 digitaldaemon.com...
 "Walter" <walter digitalmars.com> wrote in message
 news:bi6uhq$f05$1 digitaldaemon.com...
 "Mike Wynn" <mike.wynn l8night.co.uk> wrote in message
 news:bi6hdd$2rpa$3 digitaldaemon.com...
 Right. It is an error to override a final!
I have not overriden a final [the code was a little wrong]
Correct, you did not. If you did, the compiler should have issued an
error.

 but still you said `final` and non-virtual are the same.
 but they are not quite, a final functions might have a vtbl entry (but
will
 never create a new one)
Yes.
 and a final function may be entered via the vtbl it is not always called
 directly.
 I accept that from the class where it is declared final and evokes can be
 non-virtual but it does not break D semantics to always evoke member
 functions via the vtbl.
Yes, but semantically the result is the same if called through the vtbl[] or directly.
 you have chosen to optimise the final calls when you can (statically does
 what Java Jit do).
 or is that optimisation part of the D semantic spec ?
The spec doesn't mandate any optimizations, although the semantics are defined to make many kinds of optimizations possible.
Aug 24 2003
parent reply "Mike Wynn" <mike.wynn l8night.co.uk> writes:
"Walter" <walter digitalmars.com> wrote in message
news:biat6p$g81$1 digitaldaemon.com...
 "Mike Wynn" <mike.wynn l8night.co.uk> wrote in message
 news:bi8aa9$2m7h$1 digitaldaemon.com...
 "Walter" <walter digitalmars.com> wrote in message
 news:bi6uhq$f05$1 digitaldaemon.com...
 "Mike Wynn" <mike.wynn l8night.co.uk> wrote in message
 news:bi6hdd$2rpa$3 digitaldaemon.com...
 Right. It is an error to override a final!
I have not overriden a final [the code was a little wrong]
Correct, you did not. If you did, the compiler should have issued an
error.

 but still you said `final` and non-virtual are the same.
 but they are not quite, a final functions might have a vtbl entry (but
will
 never create a new one)
Yes.
right, so will D support non virtual functions, the rest of your reply quite clearly states that `final` is not non - virtual, as you originally argued (when asked about non virtual functions).
 and a final function may be entered via the vtbl it is not always called
 directly.
 I accept that from the class where it is declared final and evokes can
be
 non-virtual but it does not break D semantics to always evoke member
 functions via the vtbl.
Yes, but semantically the result is the same if called through the vtbl[]
or
 directly.
not quite, `this` can be null if invoked directly. (another reason I don't like undefined features in langs [reason I do like the Java defined eval order for all things]) the D semantice don't define anything about final, and do no do a null pointer check if the call is optimised thus will behave differently on different implementations of D.
 you have chosen to optimise the final calls when you can (statically
does
 what Java Jit do).
 or is that optimisation part of the D semantic spec ?
The spec doesn't mandate any optimizations, although the semantics are defined to make many kinds of optimizations possible.
Aug 24 2003
parent reply Ilya Minkov <midiclub 8ung.at> writes:
Mike Wynn wrote:

 not quite, `this` can be null if invoked directly.
I guess not. Direct or VTable call has nothing to do with it - "this" can only be null if you didn't create an object you're calling it on. -eye
Aug 28 2003
parent reply "Mike Wynn" <mike.wynn l8night.co.uk> writes:
"Ilya Minkov" <midiclub 8ung.at> wrote in message
news:bikrug$j5f$1 digitaldaemon.com...
 Mike Wynn wrote:

 not quite, `this` can be null if invoked directly.
I guess not. Direct or VTable call has nothing to do with it - "this" can only be null if you didn't create an object you're calling it on.
you can not call a method via the vtbl is 'this' is null (you can't get the vtbl). the original point was .... someone wanted non-virtual (so possible for 'this' to be null if the object was not initialised) walter said final which is true (when optimised to direct calls) so can be called so that the 'this' within the function is 'null' (i.e. on non initialised objects (another way to do lazy creation)) I was pointing out that final and non-virtual are different and final does not need to imply non-virtual.
Aug 28 2003
parent reply Ilya Minkov <midiclub 8ung.at> writes:
Mike Wynn wrote:
  you can not call a method via the vtbl is 'this' is null (you can't get the
 vtbl).
Nor you can call any non-static member since it's gonna dereference an offset to an object poiinter to acess members... and whoops!
 the original point was ....
 someone wanted non-virtual (so possible for 'this' to be null if the object
 was not initialised)
if you mean Dario?
 walter said final which is true (when optimised to
 direct calls) so can be called so that the 'this' within the function is
 'null' (i.e. on non initialised objects (another way to do lazy creation))
my head is spinning! In Sather it is fully normal for a function to ignore implicit this argument, which is null whenever the function is called not on an object, but on a type using a scoping operator. Or it can test it for being nil and take action. In fact, i tried to compile and tweak an exaple from Matthew Wilson, but it breaks even on the object which gets created... It may be my stupidity, or a bug, since i have an old compiler version here.
 I was pointing out that final and non-virtual are different and final does
 not need to imply non-virtual.
True. Though the virtual access would only happen if you are calling through a base class object or an interface, where it is not considered final yet. -eye
Sep 01 2003
parent "Riccardo De Agostini" <riccardo.de.agostini email.it> writes:
"Ilya Minkov" <midiclub 8ung.at> ha scritto nel messaggio
news:bj0cej$2lbh$1 digitaldaemon.com...
 Mike Wynn wrote:
  you can not call a method via the vtbl is 'this' is null (you can't get
the
 vtbl).
Nor you can call any non-static member since it's gonna dereference an offset to an object poiinter to acess members... and whoops!
I think that's a different story. You can actually _call_ a non-static function member on a null reference to an object, as long as the address of the function is known in advance (i.e. it is not virtual so there is no need to look at the vtable). The function itself is destined to no glory, though, for the reason you said. But IIRC the point to this thread was whether a D function member may check for "this" to be non-null and take appropriate (application-defined) actions otherwise. A problem that arises immediately is that in D you don't even know if a function member will end up as being virtual or not, because this is part of the automatic optimizations made by the compiler. The only way to make sure that a function member will NOT be virtual is to declare it as final in the very same class that introduces it, so that there will be only one implementation, thus no need for a vtable entry. I hope I've been of some help. As a matter of fact, this thread has gone so far that in my Outlook Express I can't even see the subject any more, because of answer indentation... :) Ric
Sep 02 2003