Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Option _Explicit Keyword(s) of day XXX:
#21
This explanation makes no sense. Could you clue us in on the role of the variables?

From what I could see:

"x" is global.
"x1" is seen only in module-level code at the top. With OPTION _EXPLICIT It throws an error inside SUB subx2 or subx3 because either it has to be declared as local there, or it has to be declared as DIM SHARED like "x". Without OPTION _EXPLICIT it's worthless, it's just set to zero and the compiler implies it's type SINGLE.
"x2" and "x3" are obvious.

With or without OPTION _EXPLICIT you HAVE TO USE DIM anyhow if you want global variables!

To create a variable local to a subprogram, STATIC could be used instead of DIM. In this case the variable is actually global, but its scope is only the subprogram that it is declared into. That way, in your example you could have as many variables named "x1" as you want, each to its own subprogram. They could be different types as one of them is required by the subprogram it is declared into.

I don't know what you mean by "throwaway" variables, there is no programming language that supports such a thing. A variable that has to be statically allocated always occupies memory at least as pointer. This is a terminal requirement of any compiler. A "symbol" is created by the compiler which is unique to the variable, and it's different from a line label or subprogram, and different from any method or property in OOP. It is up to the program or to the programmer (with dynamically allocated stuff) to make use of the memory a variable is assigned to beyond its pointer.



Somewhere in the Wiki there is an example with something like this:

Code: (Select All)
SUB someprocedure ()
STATIC ready%%
IF NOT ready%% then
    ready%% = NOT ready%%
    'set some other variables at first run of this procedure
END IF
END SUB

An example of a local variable that could act like a global variable. The catch is that the variable, at first call to the subprogram, has to be checked for value of zero or empty string. If that value (according to type) is needed then it could present a problem. That case requires a variable declared "DIM SHARED" in module-level scope, and initialized in that scope and not inside any subprogram.
Reply
#22
I'm not really sure what the point of the example code was. A simple modification is all that is needed:

Code: (Select All)
OPTION _EXPLICIT

' *** = added

' It's important to note that x1, x2, and x3, declared locally in the main module are completely
' different variables than x1, x2, and x3 that are declared locally in Subx2 and Subx3.

' If the intent was to have x1, x2, and x3 seen globally then x1, x2, and x3 could be DIM SHARED
' at the main module level removing the need to declare any variables within the subroutines.

DIM SHARED x '                         declared, global    (seen everywhere)
DIM x1 '                               declared, local     (to main module only)
DIM x2 '                           *** declared, local     (to main module only)
DIM x3 '                           *** declared, local     (to main module only)

'Main Module
x = 1 '                               declared, global    (seen everywhere)
x1 = 100 '                             declared, local     (to main module only)
PRINT "Main Module values"
PRINT "Value of x  = "; x '           declared, global    (seen everywhere)
PRINT "Value of x1 = "; x1 '           declared, local     (to main module only)
PRINT "Value of x2 = "; x2 '           not declared, local (to main module only) no longer "out of the blue"
PRINT "Value of x3 = "; x3 '           not declared, local (to main module only) no longer "out of the blue"
PRINT

Subx2
Subx3

SUB Subx2
    DIM x1 '                       *** declared, local     (to subroutine only)
    DIM x2 '                           declared, local     (to subroutine only)
    DIM x3 '                       *** declared, local     (to subroutine only)
    x2 = 200 '                         declared, local     (to subroutine only)
    PRINT
    PRINT "Subx2 Module values"
    PRINT "Value of x  = "; x '       declared, global    (seen everywhere)
    PRINT "Value of x1 = "; x1 '       declared, local     (to subroutine only) no longer "out of the blue"
    PRINT "Value of x2 = "; x2 '       declared, local     (to subroutine only) no longer "out of the blue"
    PRINT "Value of x3 = "; x3 '       declared, local     (to subroutine only) no longer "out of the blue"
    PRINT
END SUB

SUB Subx3
    DIM x1 '                       *** declared, local     (to subroutine only)
    DIM x2 '                       *** declared, local     (to subroutine only)
    DIM x3 '                           declared, local     (to subroutine only)
    x3 = 300 '                         declared, local     (to subroutine only)
    PRINT
    PRINT "Subx3 Module values"
    PRINT "Value of x  = "; x '       declared, global    (seen everywhere)
    PRINT "Value of x1 = "; x1 '       declared, local     (to subroutine only) no longer "out of the blue"
    PRINT "Value of x2 = "; x2 '       declared, local     (to subroutine only) no longer "out of the blue"
    PRINT "Value of x3 = "; x3 '       declared, local     (to subroutine only) no longer "out of the blue"
    PRINT
END SUB

Or, this could be done to limit the amount of DIM statements if the meaning was to share values:

Code: (Select All)
OPTION _EXPLICIT

' *** = added

' It's important to note that x1, x2, and x3, declared locally in the main module are completely
' different variables than x1, x2, and x3 that are declared locally in Subx2 and Subx3.

' If the intent was to have x1, x2, and x3 seen globally then x1, x2, and x3 could be DIM SHARED
' at the main module level removing the need to declare any variables within the subroutines.

DIM SHARED x '                        declared, global    (seen everywhere)
DIM x1 '                               declared, local     (to main module only)
DIM x2 '                           *** declared, local     (to main module only)
DIM x3 '                           *** declared, local     (to main module only)

'Main Module
x = 1 '                               declared, global    (seen everywhere)
x1 = 100 '                             declared, local     (to main module only)
PRINT "Main Module values"
PRINT "Value of x  = "; x '           declared, global    (seen everywhere)
PRINT "Value of x1 = "; x1 '           declared, local     (to main module only)
PRINT "Value of x2 = "; x2 '           not declared, local (to main module only) no longer "out of the blue"
PRINT "Value of x3 = "; x3 '           not declared, local (to main module only) no longer "out of the blue"
PRINT

Subx2 x2 ' x2 passed in by reference
Subx3 x3 ' x3 passed in by reference

PRINT
PRINT "Press a key"
SLEEP
CLS

PRINT "Main Module values after calls to Subx2 and Subx3"
PRINT "Value of x  = "; x '           declared, global    (seen everywhere)
PRINT "Value of x1 = "; x1 '           declared, local     (to main module only)
PRINT "Value of x2 = "; x2 '           not declared, local (to main module only) no longer "out of the blue"
PRINT "Value of x3 = "; x3 '           not declared, local (to main module only) no longer "out of the blue"
PRINT

Subx2 x2 ' x2 passed in by reference
Subx3 x3 ' x3 passed in by reference

SUB Subx2 (x2) ' x2 is passed in by local reference, x2 here is a completely different variable from x2 at main module level
    DIM x1 '                       *** declared, local     (to subroutine only)
    DIM x3 '                       *** declared, local     (to subroutine only)
    x2 = 200 '                         declared, local     (to subroutine only) change affects x2 at main module level
    PRINT
    PRINT "Subx2 Module values"
    PRINT "Value of x  = "; x '       declared, global    (seen everywhere)
    PRINT "Value of x1 = "; x1 '       declared, local     (to subroutine only) no longer "out of the blue"
    PRINT "Value of x2 = "; x2 '       declared, local     (to subroutine only) no longer "out of the blue"
    PRINT "Value of x3 = "; x3 '       declared, local     (to subroutine only) no longer "out of the blue"
    PRINT
END SUB

SUB Subx3 (x3) ' x3 is passed in by local reference, x3 here is a completely different variable from x3 at main module level
    DIM x1 '                       *** declared, local     (to subroutine only)
    DIM x2 '                       *** declared, local     (to subroutine only)
    x3 = 300 '                         declared, local     (to subroutine only) change affects x3 at main module level
    PRINT
    PRINT "Subx3 Module values"
    PRINT "Value of x  = "; x '       declared, global    (seen everywhere)
    PRINT "Value of x1 = "; x1 '       declared, local     (to subroutine only) no longer "out of the blue"
    PRINT "Value of x2 = "; x2 '       declared, local     (to subroutine only) no longer "out of the blue"
    PRINT "Value of x3 = "; x3 '       declared, local     (to subroutine only) no longer "out of the blue"
    PRINT
END SUB
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Reply
#23
Hello mnrvovrfc

Quote:This explanation makes no sense. Could you clue us in on the role of the variables?
 
Perhaps I could have come up with a better algorythm to demonstrate how Option _Explicit seems to eliminate a local variable, you pretty well have to Dim Shared all your variables and make them global. If you run the code I provided without Option _Explicit you can see where the x variable, when only Dim'd (not Shared) will come up with the correct value exactly in the module where it has been Dim'd. You can count on any other use of a variable Dim'd in a different module to = 0. 

Quote:I don't know what you mean by "throwaway" variables, there is no programming language that supports such a thing.
Ya, it's the programming language of DimBasic. I generally think of single use variable like for a counter or a local variable as one which serves it purposes and can be discontinued as 'no longer material to the ultimate results of the program', as a throwaway. Its a very important key word in DimBasic. 

And Terry (The Best of the Best)
I was trying to create real local variables in my subroutines and Not pass any reference values. The point being a Dim'd value is local by it's nature. Option _Explicit tends to stop the creation of a local variable in a subroutine. I hope this example demonstrates that point 

Code: (Select All)
'Option _Explicit

Dim x
'Dim Shared x2
x = 1

Print x
Subx2

Sub Subx2
    Dim x2
    x2 = 100
    Print x2
End Sub
Here I have a local variable in the main module declared by a simple Dim x, and a second local variable in the subroutine also declared by a simple Dim. Because I have Option _Explicit commented out when you run the code the answers are correct, but if you uncomment Option _Explicit that x2=100 is problematic. You have to Dim Share it and comment out the Dim x2 in the subroutine. As you correctly point out, there is always passing the value by reference but to me, and considering what an expert I am in Basic coding, a variable relying on a reference value is no longer a "throwaway" variable. (ok Steve to use this definition in your Bible)

Option _Explicit has me making all variables global and the "throwaway" thrown away. The bonus is I now have very meaningful variable counters like

For NutsINtheJar = 1 to 1000Tonguerint "Place a Nut in the Jar": Next
Reply
#24
The thing going on about "x2" in the second example just above is good for programmers who don't want to give outlandish names to variables. With OPTION _EXPLICIT and the DIM SHARED going down for "x2", it's actually being protected in the subprogram by the local "x2". Yes sometimes this could get in the way, but some programmers appreciate something like this. There is nothing to do about it except create a parameter for the subprogram and pass the global "x2" as that parameter. Then the value of global "x2" could be changed or not as you (the programmer) decides.

Be glad we're programming in BASIC and not eg. in Python where it is required to tell the interpreter which variables are global inside a function definition.
Reply
#25
There is one thing that occurred to me.

What if your code is a "trade secret" you want to protect, but some reason you have to post it somewhere or you have to share it with someone?

Without OPTION _EXPLICIT you would have to look for another programming language to do obfuscation.

With a language like Freebasic which enforces OPTION _EXPLICIT without needing a similar code line, in its normal programming mode, you could get away with object-oriented programming only with "A", "B", "C" and "D" as variables throughout, if you're clever enough. If the language featured case-sensitive variables then "A", "a", "B" and "b" would have boggled the mind even more...

I have actually seen such an example (of C++ code) as an "advertisement" somewhere inside MSDN.
Reply
#26
(06-09-2023, 07:12 PM)mnrvovrfc: Wrote: What if your code is a "trade secret" you want to protect, but some reason you have to post it somewhere or you have to share it with someone?

Then either you trust that person and they have the proper clearance to see/edit/access your "trade secret" process, or else you end up going to court over violation of intellectual property rights and forfeiture of any non-disclosure agreement which you signed.  Changing variable names from a readable Screen_Position_X to SPX isn't enough to allow for such to still not be considered a breach of your agreement.

Option _Explicit does not allow one to just change a few names to obfuscate their code so they can get around any sort of "trade secret" clause.  I certainly know any boss that I've ever worked for in my life would have his eyeballs pop out of his head Wile E Coyote style, and then he'd attach the person who suggested the concept to the closest Acme rocket and pair of rollerskates and happily launched them off towards the closest unemployment office.
Reply
#27
That Happy Face in my last remarks was a surprise, an unintended consequence to trying to write a full colon and a capital P after it. Like this Tongue (Tongue) but without the brackets.
Reply
#28
(06-10-2023, 02:05 PM)Dimster Wrote: That Happy Face in my last remarks was a surprise, an unintended consequence to trying to write a full colon and a capital P after it. Like this Tongue (Tongue) but without the brackets.
There are a bunch
Wink  that's semi colon + )

Big Grin that's : + D

Oh! click the [get more] link! Cool
b = b + ...
Reply




Users browsing this thread: 1 Guest(s)