Type gone and back

Archives Forums/Blitz3D Bug Reports/Type gone and back

Fernhout(Posted 2012) [#1]
I do not know if this is realy a bug. But its strike me that the following code give some result is do not expect to get. The following code is from the example help file and adjusted it a little bit.

If you look close to the code you see i made a type a.Alien and put 10 in a\x.
The i made another a.Alien

i delete 1
then i go to the last type and its stil there.

Then the program made a new one a.Alien.
program check and say yes its there.
And delete it again.
the program check it again and say no there is no type left

then the call to the last type is done.
And printing the a\x value. I got no error but the result 10 on the screen.

Why say BB that the a.alien is gone and there is sill one left?

Can someone explain to me whats going on here.





H&K(Posted 2012) [#2]
A is a label to An Alien

a points to alien x= 10
a points to new Alien
The Label "a" points to NO Alien (Was Deleted)

Tell "a" to point to last alien.
a Points to x=10 Alien

A points to new alien
The label "a" points to NO Alien (was Deleted)

; stil the program say no ther is no more
If a = Null Then Print "Alien gone!"
A points to NO Alien

Tell "a" to Point to last Alien.
A points to Alien x=10

Last edited 2012

Last edited 2012


Fernhout(Posted 2012) [#3]
Ok i understand your explenation. And that means that when i have a large number of labels of one type, and i delete one, i can check to see if its gone and i have to point to the next or previous one to see the data of the existing label.

Pretty big work for deleting a label.

In my program was this problem giving me an error. After trial and error methode i found this out.

To know if the real type is empty you have to go to the first or last label
cause if the label realy is not there then the check say its empty.

Its good to know.


H&K(Posted 2012) [#4]
Yes and no.

Pretty big work for deleting a label.
You are not deleting the label, you are deleting the instance of the type the label is "labelling"/Pointing to at that moment.

Although you have found it confusing/difficult its one of the things B3d does to make programming easier.

Last edited 2012


Zethrax(Posted 2012) [#5]
The 'New' command creates an object of the Type you specify, adds it to a linked list that holds all the objects of that Type, and then returns a pointer to the object you just created. In the case of 'a.Alien = New Alien' you're creating an object of Type 'Alien' and storing its object pointer in the pointer variable 'a.Alien'.

The problem with your code is that you're storing all your object pointers in the same pointer variable, so each pointer value you store in that variable is overwriting the one stored before it and you're then checking that value to see if all the objects have been deleted. Since you did delete the last object you stored a pointer to in that variable then naturally checking that variable will tell you that it has been deleted (as object pointers use indirection).

So basically you've created three objects in your code and then deleted two of them. The pointer value stored in a.Alien has been overwritten a couple of times and is unreliable at the point where you check it in the code 'If a = Null Then Print "Alien gone!"'. The only reason you're getting a value returned that has any meaning at all there is because Blitz3D uses indirection (the object pointer points to an indirection pointer which points to the actual object) and the indirection pointer was nullified when you deleted the object it pointed to. Under different circumstances, checking that object pointer may have returned invalid data that could have caused problems if you'd tried to make use of it.

In the line 'a.alien = Last alien' you set the pointer variable 'a.alien' to hold a pointer to the last remaining 'Alien' object, which is actually the first object of Type 'Alien' that you created and never deleted. Since this was the object that you actually modified a field of, checking its value of that field for that object returns the value you set.

Try to avoid writing code where you need to check if an object has been deleted. Instead, use the linked list that all objects of a specific type get added onto to sequence through your remaining objects of that Type and carry out any functions you need to carry out for them. Or alternatively, store your object pointers on an array and nullify the array slot for any object that you delete. That way you know that you're dealing with reliable data that isn't getting overwritten.


Fernhout(Posted 2012) [#6]
Thanks for the education. I understand now the whole consept of null pointer. B3D is kind a messy if its come to type with the same label namems.

I am busy programming a turn based game, and had some problems using delete on a type. thats why this question. During the game ships is goming and going pretty fast in the game. That means 1 turn i have 10 ships and the next turn i lose 4 ships. ect...
Because op the position of every ship and the differend types of ships i can nod delete any kind of type. Every type who is connected to a specific ship must deleted if needed.
That mean that i delete a type and was expecting that the whole pointer was shifting so the list of labeled types are complete. I was thinking that the next type was writable. I got an error when i did try it. later on i discoverd it and now im checking the contance if the type of ship is the right one.

thanks guys.


_PJ_(Posted 2012) [#7]
My advice is not to use the same 'label':

Function SpawnAlien.Alien()
   NewAlien.Alien = New Alien
   NewAlien\Health=10
   Return NewAlien.Alien
End Function

;...

For IterateAlien.Alien = Each Alien
   If (IterateAlien\Health<1)
       DeleteAlien(IterateAlien.Alien)
   End If
Next

;...

Function DeleteAlien(DestroyAlien.Alien)
   If (DestroyAlien.Alien<>Null) ; Always handy to have a check for Null pointer
      Delete DestroyAlien.Alien
   End If
End Function

;...


This way, it's less likely to get confused with the labels and their reference targets :)


H&K(Posted 2012) [#8]
My advice is not to use the same 'label':
I would go even further and suggest you use some form of notation when meaning "things". Say always start Type names with a T, and member variables with a _ and locals with a L.

Which you use isn't important, just when you come back to reread some code and see TName you know this is the type itself etc.


Yasha(Posted 2012) [#9]
Say always start Type names with a T, and member variables with a _ and locals with a L.


Side note: the reason for the TConvention in BlitzMax is because BlitzMax has a single namespace for types (which can exist at runtime as metaobjects), functions (which can be values, thanks to function pointers) and variables. Blitz3D, not permitting types or functions to be used as values, puts them in separate namespaces. Therefore it's perfectly possible and legitimate (if unreadable) to have a type, function and global all with the same identifier, as they will never collide (e.g. "Global myType.myType = myType()").

Blitz3D names also can't begin with an underscore (I'm guessing that's reserved to make life easier for the linker?).