FreeBASIC syntax challenge games

For other topics related to the FreeBASIC project or its community.
fxm
Posts: 10036
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Postby fxm » Jan 03, 2020 20:02

I'll let you all think a little more before I reveal my last clue.
dodicat
Posts: 6755
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: FreeBASIC syntax challenge games

Postby dodicat » Jan 03, 2020 20:19

I don't see an easy way of not de-referencing the pointer each time to look for the integer value.
Here I have simplified my method, and added a running loop.
I have no leaks showing in the resource monitor, and have not had a crash in > 200000 loops.
(Which isn't foolproof by any means I realize)

Code: Select all



#macro TypeHasDtor(TypeSymbol, TypeHasDtorResult)

    type udt##typesymbol
        as typesymbol  x
    end type
    var Num##typesymbol=5 'an arbitrary number of instances
    dim  as udt##typesymbol ptr p##typesymbol=new udt##typesymbol[Num##typesymbol]
    dim as integer ptr ip##typesymbol=cast(integer ptr,cast(any ptr,p##typesymbol))
    TypeHasDtorResult=iif(*(ip##typesymbol-1)=Num##typesymbol,true,false) 'dereference here
    delete[] p##typesymbol
#endmacro

'looper
#macro TypeHasDtorrun(TypeSymbol, TypeHasDtorResult)
     Num##typesymbol=10+rnd*500 'an arbitrary number of instances
     p##typesymbol=new udt##typesymbol[Num##typesymbol]
     ip##typesymbol=cast(integer ptr,cast(any ptr,p##typesymbol))
    TypeHasDtorResult=iif(*(ip##typesymbol-1)=Num##typesymbol,true,false)
    delete[] p##typesymbol
#endmacro


Dim As boolean hasDtorResult

TypeHasDtor(Integer, hasDtorResult)
Print "The 'Integer' Type has a destructor (implicit or explicit): ", hasDtorResult

TypeHasDtor(String, hasDtorResult)
Print "The 'String' Type has a destructor (implicit or explicit): ", hasDtorResult

Type string10Type As String * 10  '' define an alias to get a symbol name
TypeHasDtor(string10Type, hasDtorResult)
Print "The 'String * 10' Type has a destructor (implicit or explicit): ", hasDtorResult

Type stringptrType As String Ptr  '' define an alias to get a symbol name
TypeHasDtor(stringptrType, hasDtorResult)
Print "The 'String Ptr' Type has a destructor (implicit or explicit): ", hasDtorResult

TypeHasDtor(Object, hasDtorResult)
Print "The 'Object' Type has a destructor (implicit or explicit): ", hasDtorResult

Type UDT1 Extends Object
End Type
TypeHasDtor(UDT1, hasDtorResult)
Print "The 'UDT1' User-Type has destructor (implicit or explicit): ", hasDtorResult

Type UDT2 Extends Object
    Declare Destructor ()
End Type
Destructor UDT2 ()
End Destructor
TypeHasDtor(UDT2, hasDtorResult)
Print "The 'UDT2' User-Type has destructor (implicit or explicit): ", hasDtorResult
'====================================
cls
dim as long counter
do
    counter+=1
    locate 4,,0
TypeHasDtorRun(Integer, hasDtorResult)
Print "The 'Integer' Type has a destructor (implicit or explicit): ", hasDtorResult

TypeHasDtorRun(String, hasDtorResult)
Print "The 'String' Type has a destructor (implicit or explicit): ", hasDtorResult


TypeHasDtorRun(string10Type, hasDtorResult)
Print "The 'String * 10' Type has a destructor (implicit or explicit): ", hasDtorResult


TypeHasDtorRun(stringptrType, hasDtorResult)
Print "The 'String Ptr' Type has a destructor (implicit or explicit): ", hasDtorResult

TypeHasDtorRun(Object, hasDtorResult)
Print "The 'Object' Type has a destructor (implicit or explicit): ", hasDtorResult


TypeHasDtorRun(UDT1, hasDtorResult)
Print "The 'UDT1' User-Type has destructor (implicit or explicit): ", hasDtorResult


TypeHasDtorRun(UDT2, hasDtorResult)
Print "The 'UDT2' User-Type has destructor (implicit or explicit): ", hasDtorResult
print "Runs ";counter
loop
Sleep
Last edited by dodicat on Jan 04, 2020 10:48, edited 1 time in total.
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: FreeBASIC syntax challenge games

Postby Tourist Trap » Jan 03, 2020 20:30

fxm wrote:I'll let you all think a little more before I reveal my last clue.

I think I'm wrong, I just do the job from inside a UDT and pray for that the UDT is smarter than me, and he certainly is.

Code: Select all

type DESTRUCTABLE_UDT
   declare destructor()
   as integer ii
end type
destructor DESTRUCTABLE_UDT()
   this.ii = -1
end destructor

type TEST
   as DESTRUCTABLE_UDT ptr uu = new DESTRUCTABLE_UDT [1]
end type
dim as TEST tt
? cast(integer ptr, tt.uu)[-1]
delete[] tt.uu
? cast(integer ptr, tt.uu)[-1]

type TEST2
   as OBJECT ptr        oo = new OBJECT [1]
end type
dim as TEST2 tt2
? cast(integer ptr, tt2.oo)[-1]
delete[] tt2.oo
? cast(integer ptr, tt2.oo)[-1]

' 1
' 11998904
' 201387456
' 60864


Looking at what dodicat is doing, I can only guess that that won't be so trivial a thing.
dodicat
Posts: 6755
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: FreeBASIC syntax challenge games

Postby dodicat » Jan 03, 2020 20:35

Hello TT, you've been away for a while?
The only non trivial thing about mine is the silly names I give to the variables in the macro.
fxm
Posts: 10036
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Postby fxm » Jan 03, 2020 20:37

fxm wrote:- Second clue lowering Enigma #25 to force 3: The macro principle is to apply the New [] operator on an UDT containing a single data member of the Type to test, and to safely check if an Integer (to store the number of instances to destroy) is added ahead the user instances block in the allocated memory. Consequently, the address of the user instances block is different from that of the global allocated memory.

The problem therefore remains to find how to retrieve the address of the allocated global memory, in order to compare it with the address of the block of user instances.
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: FreeBASIC syntax challenge games

Postby Tourist Trap » Jan 03, 2020 20:47

dodicat wrote:Hello TT, you've been away for a while?
The only non trivial thing about mine is the silly names I give to the variables in the macro.

Hi dodi! You always in the breach I can see :) For me, been kept stuck with passing exams for certification at work... Doing PyQT and VB stuff, in the good days, and trying to learn schoolish stuff the rest of the time ! :)

fxm wrote:The problem therefore remains to find how to retrieve the address of the allocated global memory, in order to compare it with the address of the block of user instances.

Maybe a null pointer of an instance could do? I remember having been successful in considering that as something that can access static stuff from a UDT. This would be interesting to have a way to force the program to crash if wrong :)

Don't know what to think of that. Can't do static stuff with pointers anyway it seems.

Code: Select all

type DESTRUCTABLE_UDT
   declare destructor()
   as integer ii
end type
destructor DESTRUCTABLE_UDT()
   this.ii = -1
end destructor

type TEST
   as integer ii
   as DESTRUCTABLE_UDT ptr uu  => new DESTRUCTABLE_UDT[1]
end type

dim as TEST ptr tt = new TEST[1]

? cast(integer ptr, tt->uu)[-1]

delete[] tt->uu

? cast(integer ptr, tt->uu)[-1]

type TEST2
   as integer ii
   as OBJECT ptr oo  => new OBJECT[1]
end type

dim as TEST2 ptr tt2 = new TEST2[1]

? cast(integer ptr, tt2->oo)[-1]

delete[] tt2

? cast(integer ptr, tt2->oo)[-1]

getKey()


with destructor
1
11624400
without destructor
1729462852465798528
0
fxm
Posts: 10036
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Postby fxm » Jan 04, 2020 7:30

Tourist Trap wrote:
fxm wrote:The problem therefore remains to find how to retrieve the address of the allocated global memory, in order to compare it with the address of the block of user instances.

Maybe a null pointer of an instance could do?

No, this is not the direction to go.
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: FreeBASIC syntax challenge games

Postby Tourist Trap » Jan 04, 2020 9:30

fxm wrote:No, this is not the direction to go.

Is there a way to do something by adding a destructor in the encapsulated fake udt? Then, seems to me, in any case, that there would be some room reserved for the an extra integer. Maybe worth a try.

Edit(2): This below worked ... and tests the integer ahead. Safe or not, the question remains.

Code: Select all

type NOTDESTR_UDT as OBJECT

type DESTR_UDT
   declare destructor()
   as integer dii
end type
destructor DESTR_UDT()
   this.dii = -1
end destructor

#macro TypeHasDtor(T, R)
   ? #T,
   type EAT_UDT_##T as T
   
   type CAPPEDT_UDT_##T
      declare destructor()
      as T ptr tptr = new T[1]
   end type
   destructor CAPPEDT_UDT_##T
      delete[] this.tptr
   end destructor
   
   dim as CAPPEDT_UDT_##T    cap_##T
   
   scope
      var before = cast(integer ptr, cap_##T.tptr)[-1]
      delete[] cap_##T.tptr
      var after = cast(integer ptr, cap_##T.tptr)[-1]
      ? before, after
      R = (before - 1)
   end scope
#endMacro


dim as boolean          res
TypeHasDtor(DESTR_UDT, res) : ? res
TypeHasDtor(NOTDESTR_UDT, res) : ? res
TypeHasDtor(integer, res) : ? res

DESTR_UDT 1 6499056
false
NOTDESTR_UDT 201352998 26406
true
integer 201352998 26406
true
fxm
Posts: 10036
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Postby fxm » Jan 04, 2020 10:23

I got this with your code:

Code: Select all

DESTR_UDT      1             8388800
false
NOTDESTR_UDT   201332298     5706
true
integer        201332298     5706
true

Aborting due to runtime error 12 ("segmentation violation" signal) in C:\Users\fxmam\Documents\Mes Outils Personnels\FBIde0.4.6r4_fbc1.08.0\FBIDETEMP.bas::()

Two 'DELETE []' for one 'NEW []' !
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: FreeBASIC syntax challenge games

Postby Tourist Trap » Jan 04, 2020 10:48

fxm wrote:I got this with your code:

Code: Select all

Aborting due to runtime error 12 ("segmentation violation" signal) in C:\Users\fxmam\Documents\Mes Outils Personnels\FBIde0.4.6r4_fbc1.08.0\FBIDETEMP.bas::()

Two 'DELETE []' for one 'NEW []' !

Have to find where. I didn't see that.
EDIT, ahah yes. Is this better:

Code: Select all

destructor CAPPEDT_UDT_##T
      if this.tptr>0 then delete[] this.tptr
end destructor


Anyway so it seems that cast(integer ptr, T.tptr)[-1] is not equal to cast(integer ptr, @T)[-1] when *tptr has no destructor.
Other try with inheritance:

Code: Select all

type NOTDESTR_UDT as OBJECT

type DESTR_UDT
   declare destructor()
   as integer dii
end type
destructor DESTR_UDT()
   this.dii = -1
end destructor

#macro TypeHasDtor(T, R)
   '? #T,
   
   type CAPPEDT_UDT_##T
      as T tt
   end type
   
   type EXTENDCAPPEDT_UDT_##T extends CAPPEDT_UDT_##T
      as T ptr tptr = new T[1]
   end type
   
   dim as EXTENDCAPPEDT_UDT_##T  extcap_##T
   
   scope
      var before = cast(integer ptr, extcap_##T.tptr)[-1]

      delete[] extcap_##T.tptr

      var after = cast(integer ptr, extcap_##T.tptr)[-1]

      ? before, after
      R = (before - 1)
   end scope
#endMacro


dim as boolean          res
TypeHasDtor(DESTR_UDT, res)      : ? not res
TypeHasDtor(NOTDESTR_UDT, res)   : ? not res
TypeHasDtor(integer, res)        : ? not res

1 11348720
true
201365843 39251
false
201365843 39251
false

Safer??
fxm
Posts: 10036
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Postby fxm » Jan 04, 2020 11:52

When one uses the OBJECT type (directly or inherited), a hidden vptr member (virtual pointer) is added to the user member data (at first position) allowing to access the vtbl (virtual table).
Therefore, @instance value is different from @first_user_data_member value (because the hidden vptr is located at @instance address).
fxm
Posts: 10036
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Postby fxm » Jan 04, 2020 12:02

Tourist Trap wrote:Safer??

var before = cast(integer ptr, extcap_##T.tptr)[-1]
is unsafe because the corresponding memory is not allocated when the type T has no destructor.

var after = cast(integer ptr, extcap_##T.tptr)[-1]
is doubly unsafe, because the instance has been in addition destroyed and deallocated (by DELETE []) just before.
fxm
Posts: 10036
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Postby fxm » Jan 04, 2020 12:13

Tourist Trap wrote:Is there a way to do something by adding a destructor in the encapsulated fake udt?
Little free clue: Yes some member must be added in the macro Type, but not a Destructor().

Tourist Trap wrote:Then, seems to me, in any case, that there would be some room reserved for the an extra integer.
No (only when the Type has a destructor and that NEW [] is used).
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: FreeBASIC syntax challenge games

Postby Tourist Trap » Jan 04, 2020 15:21

fxm wrote:
Tourist Trap wrote:Is there a way to do something by adding a destructor in the encapsulated fake udt?
Little free clue: Yes some member must be added in the macro Type, but not a Destructor().

Damn, thank you for all the information.
I will use your clue, and I'm obtaining this. Don't ask me why it say the truth, but for now it seems working :)

Code: Select all

type DESTR_UDT
   declare destructor()
   as integer dii
end type
destructor DESTR_UDT()
   this.dii = -1
end destructor

#macro TypeHasDtor(T, R)
   ? #T,
   
   type CAPPEDT_UDT_##T
      static as integer si##T
      as T ptr tt = new T [1]
   end type
   dim as integer CAPPEDT_UDT_##T.si##T = any
   
   dim as CAPPEDT_UDT_##T  cap_##T
   
   scope
      var before = cast(integer ptr, @CAPPEDT_UDT_##T)[1]

      delete[] cap_##T.tt

      var after = cast(integer ptr, @CAPPEDT_UDT_##T)[1]

      ? before, after
      R = iif(before<>after, 1, 0)
   end scope
#endMacro


dim as boolean          res
TypeHasDtor(DESTR_UDT, res)      : ? res
TypeHasDtor(OBJECT, res)   : ? res
TypeHasDtor(integer, res)        : ? res

DESTR_UDT 0 1
true
OBJECT 0 0
false
integer 11741968 11741968
false

Your verdict?
fxm
Posts: 10036
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Postby fxm » Jan 04, 2020 15:46

In addition to be always unsafe, your code (that I does not understand) does not even output the right response on my PC:

Code: Select all

DESTR_UDT      1703480       4598484
true
OBJECT         4598468       4598512
true
integer        4598496       4598544
true
    (with Win32 and gas for example)

Return to “Community Discussion”

Who is online

Users browsing this forum: No registered users and 6 guests