Working without Strict?

BlitzMax Forums/BlitzMax Programming/Working without Strict?

John Pickford(Posted 2010) [#1]
I'm attempting to port our current game to mac using MiniB3D. One of the issues with the library means I have to remove 'Strict'. This seems to be causing problems though.

Strict


	Local x=1

	If  x=1


		Local y=3


	Else

		Local y=4


	EndIf


This code compiles in strict mode but if you remove the strict I get a duplicate identifier on the y=4 line.

Does this mean the strict alters the scope of local variables?


ziggy(Posted 2010) [#2]
Does this mean the strict alters the scope of local variables?

Yes. Local variables when using SCOPE are at block level. It means, a local declared insude a while, won't be accesible outside the loop, a variable declared inside the IF won't be available outside, etc. This forces a much more organized way to deal with locals, and lets the compiler perform additional optimizations storing those locals to registers when possible.

You can use Minib3d as a module and forget about this, let the module be 'strict' and make your code not-strict if you really don't want to take the time to rewrite it in a strict way (wich is something I would recommend you to do).


John Pickford(Posted 2010) [#3]
My code is strict but it seems I have to remove it for minib3d.

From the minib3d readme:

"When using MiniB3D, you will have to use ints to store entity handles rather than using objects directly, i.e. cam=CreateCamera() rather than cam:TCamera=CreateCamera(). This means you will not be able to use Strict/SuperStrict."


Yan(Posted 2010) [#4]
I never actually got round to using MiniB3D, but the version I have (v0.52) uses strict as do most of the examples.

Are you using an old version or something?


[edit]
Ah...It appears the unstrict'ness is only required when using MiniB3D in conjunction with the B3DSDK.

You mentioned that you were using this for the Mac, so I assume this doesn't apply to you as the B3DSDK is Win32 only, is it not?
[/edit]


John Pickford(Posted 2010) [#5]
The PC version uses B3dsdk. I'm porting to mac using Minib3d.


Yan(Posted 2010) [#6]
Oh, right. It should 'just' be a case of still using strict, converting your integer handles, where appropriate, to objects and adjusting the function names then??

Assuming you haven't used any features of the SDK that don't appear in MiniB3D and bearing in mind that I haven't used either product, of course. :o/


John Pickford(Posted 2010) [#7]
Well yes. I'm just trying to get my head around the whole thing.

I'm confused by the way STRICT seems to be altering the scope of locals. I had no idea that my code would become dependent on STRICT. I thought it was something that could be removed at any time.

Is there a full description of what STRICT does to the scope of variables anywhere?


Dreamora(Posted 2010) [#8]
sure you are on the current version of minib3d, not using some old one, if you have the strict problem?


And script does a lot: removes goto, removes int object handles, introduces the whole scopes (without strict there is exactly one closed scope, thats functions) and without strict, many GC optimizations are gone (required to make the int handle crap even possible). Simply put, without strict it is not bm, but some extended form of b3d / bplus


John Pickford(Posted 2010) [#9]
I have version 0.53.

Sounds like I don't want to lose Strict.

What I'm hoping to do is get my game working on the Mac using the same source code whilst keeping B3DSDK on PC and using MiniB3D on Mac. Obviously there will be some differences and plenty of ?Win3d and ?Macos but I don't want to split the development into two.

Another option is to convert to using MinB3d on both formats but I don't want to embark on that path till I'm sure the game will work well with MiniB3d.


Yan(Posted 2010) [#10]
[edit]Oops...This took *much* longer than it should have. ;o/[/edit]

Sorry, my previous post wasn't particularly clear. My point was; you don't need to remove strict, or should IMHO, just convert your existing code to use objects etc.


There was a nice explanation of Strict behaviour on the old Wiki but, alas, that's long since gone. :o(

The Official Docs have this to say on the subject:-
Strict mode
Classic BASIC allows you to declare variables 'on the fly'. For example, consider a program consisting of:

For k=1 To 10
sum=sum+k
Next
Print sum
This program automatically creates 2 local variables: 'k' and 'sum'. However, this behaviour can often lead to unexpected bugs. For example, if you mistyped one of the 'sum' variables, the program would not work as expected. No error would be given - a new variable would simply be created.
By default, BlitzMax will allow you to automatically declare variables like this. However, you can use the Strict command to override this behaviour.

Strict must appear at the top of your program before any actual program code and puts your program into 'strict mode'. Strict mode forces you to declare all variables before use. For example, rewriting the above program in strict mode results in:

Strict
Local sum,k
For k=1 To 10
sum=sum+k
Next
Print sum
If you were to mistype one of the variable names in this program, you would receive an 'identifier not found' error when compiling, allowing you to easily find and correct the problem.
Which isn't particularly useful.

Here are the main points-
---------------------------------------------------------------------------------------------
                  Strict                      |                  Non-Strict
----------------------------------------------|----------------------------------------------
  Local variables scoped to                   |  Local variables scoped to function/method
  'code block boundaries'                     |  boundaries
                                              |
  Manual conversion between objects           |  Auto coversion between object and integer
  and integer handles Via HandleFromObject()  |  handles
  and HandleToObject()                        |
                                              |
  No Goto                                     |  Goto #label
                                              |
  Exit will jump out of of current code block |  Exit will jump out of current code block
  or multiple code blocks tagged with #label  |  only
                                              |
  Variables must be declared                  |  Undeclared varibale will be automatically 
                                              |  assigned
----------------------------------------------|----------------------------------------------
                    +                         |                      -
  Speed increase from compiler being able to  |  Speed hit when not using object declarations
  'cache' variables in local scopes           |  due to object<->handle conversion
                                              |
                                              |  integer handles need to be manually freed
                                              |  easy to produce 'leaky' code
---------------------------------------------------------------------------------------------



Yan(Posted 2010) [#11]
What I'm hoping to do is get my game working on the Mac using the same source code whilst keeping B3DSDK on PC and using MiniB3D on Mac. Obviously there will be some differences and plenty of ?Win3d and ?Macos but I don't want to split the development into two.
Can't you knock up a quick 'B3DSDK wrapper' for MiniB3D?
EG...
...ETC...

Function bbCreateCamera(parent=0)
  Return HandleFromObject(CreateCamera(parent))
End Function

Function bbFreeEntity(entity)
  TEntity(HandleToObject(entity)).FreeEntity()
  Release entity
End Function

...ETC...
...If only to see if everything works as expected. You'd then have the option of converting it to use MiniB3D, as described above, if the speed hit was too much.


ima747(Posted 2010) [#12]
I'm unfamiliar with B3DSDK proper, and I assume that since you're trying to keep backwards code base compatibility that's where the problem is coming from, in that you don't want to convert object types (I gather from int pointers in B3D to objects in BMax/MiniB3D).

I use superstrict in all my projects and have been using minib3d for a long time now on mac and PC without any problem. I would recommend you knock together an example to test MiniB3d and try cross compiling it for mac and PC.

Following that assuming you're happy with the outcome I would look at porting your project to MiniB3d and maintaining it there. Obviously this may not be reasonable for your project, but IMO maintaining 1 code base an compiling for different targets will be much easier than trying to maintain 2 cores.

I personally would opt for a translation rather than dropping strict due to the can of worms you're already seeing, but also tighter code is generally better code (execution speed, stability, readability etc. etc.)


William Drescher(Posted 2010) [#13]
After reading the above posts, I can see that some of this can be a little confusing. From what I can see, if you move the Local call outside of the If statement, your code will run both in Strict and in Non-Strict modes almost seamlessly.

For clarification purposes, the reason you get a duplicate identifier error without strict is because the scope of the variable Y in the particular code is within the "main" function, a.k.a. the main program call. When strict is active, the scope of the Y variable moves to being inside the If call and therefor can be declared with Local based on conditional methods.

As explained in Yan's chart, variables are scoped to their code blocks defined with If/Then, Method, Function, Select/Case, etc, when strict is on. SuperStrict takes this further and requires you to define the variables type when instantiated, further limiting 'on-the-fly' variable creation.

Quick example:
Strict

Local x=1
Local y

if x=1
    y=2
Else
    y=3
End If



Jesse(Posted 2010) [#14]
From what I understand, as related to "variables", the only difference between Strict and SuperStrict is that SuperStrict requires declaration of Int variables as "Int" while strict does not. Every other variable type works the same way in Strict And SuperStrict and I suspect is the reason why mark made the "Little Survey!" My guess is, he was considering removing SuperStrict as there is not really much else to it.