When a virtual member procedure or a static member procedure (or variable) is called (or accessed) on an object returned from a function, the function is called respectively twice or not at all!
Code to highlight the bug:
Type UDT Extends Object
Declare Virtual Sub info_virtual ()
Declare Static Sub info_static ()
Static As Integer int_static
End Type
Dim As Integer UDT.int_static = 1
Virtual Sub UDT.info_virtual ()
Print " UDT.info_virtual()"
Print UDT.int_static
End Sub
Static Sub UDT.info_static ()
Print " UDT.info_static()"
Print UDT.int_static
End Sub
Function inc (Byref u As UDT) Byref As UDT
Print " inc()"
UDT.int_static += 1
Return u
End Function
Dim As UDT u
Print "'Print UDT.int_static':"
Print UDT.int_static
Print
Print "'inc(u).info_virtual()':"
inc(u).info_virtual() '' *** Bug : function inc() called twice!
Print
Print "'inc(u).info_static()':"
inc(u).info_static() '' *** Bug : function inc() not called at all!
Print
Print "'Print inc(u).int_static':"
Print inc(u).int_static '' *** Bug : function inc() not called at all!
Sleep
Output:
'Print UDT.int_static':
1
'inc(u).info_virtual()':
inc()
inc()
UDT.info_virtual()
3
'inc(u).info_static()':
UDT.info_static()
3
'Print inc(u).int_static':
3
Referring at forum from post http://www.freebasic.net/forum/viewtopic.php?p=196522#p196522
To clarify, there are two problems:
vtable lookups re-use (duplicate) the This argument expression without handling/working-around side-effects in it. Thus any functions in the This expression are being called twice, but shouldn't be.
static method calls delete the This argument expression without handling side-effects. Thus any functions in the This expression aren't being called but probably should be.