QB64.org Forum

Active Forums => QB64 Discussion => Topic started by: SMcNeill on August 12, 2019, 01:17:04 am

Title: Option Explicit doesn't work with SHARED?
Post by: SMcNeill on August 12, 2019, 01:17:04 am
Code: QB64: [Select]
  1. fooinit
  2. fooprint
  3.  
  4. SUB fooinit
  5.     SHARED test AS INTEGER
  6.     test = 2
  7.  
  8. SUB fooprint
  9.     SHARED test AS INTEGER
  10.     PRINT test

The above code works perfectly fine.  Our variables are named and SHARED inside the SUBs with no problem -- unless we add an OPTION _EXPLICIT to the top of the code:

Code: QB64: [Select]
  1.  
  2. fooinit
  3. fooprint
  4.  
  5. SUB fooinit
  6.     SHARED test AS INTEGER
  7.     test = 2
  8.  
  9. SUB fooprint
  10.     SHARED test AS INTEGER
  11.     PRINT test

We're now getting an ERROR -- "Variable not defined"  -- for test.  Is this how Option Explicit is supposed to work (rendering variable sharing internally between subs impossible unless they're declared globally), or is this a glitch?  I'm not one to normally use OPTION _EXPLICIT, so I never wouldn't noticed the issue, if Bplus wouldn't have pointed it out for his Pizza Menu program.

Title: Re: Option Explicit doesn't work with SHARED?
Post by: RhoSigma on August 12, 2019, 01:52:51 am
Try to COMMON SHARED the variables right after OPTION _EXPLICIT. However, best way would be to allow DIM SHARED within SUBs/FUNCs, guess that would be the easiest fix.

BTW - I still dont like this OPTION _EXPLICIT thing. Somebody who needs such a semi-automatic system to keep track of the variables in his project, is no real coder IMHO. However, I currently revise my libraries collection again to add all these nonsense DIMs, so unexperienced users have no trouble with missing variable definitions in case they use OPTION _EXPLICIT, but I hate it.
Title: Re: Option Explicit doesn't work with SHARED?
Post by: TempodiBasic on August 12, 2019, 07:58:05 pm
Hi
I find logic the error pointed out by Option _explicit
why?
simple, we using SHARED  in closed block like SUB and FUNCTION to pass that inner variable to the main block.
But in the main block there is no definition of that variable which SHARED forced to be, so Option _Explicit does it work to show what is not declared explicitly.
To let work in different style Option _Explicit can give a warn and no halt the compilation because its goal is to give information to the user and not to correct the syntax.
What do you think about this?
Title: Re: Option Explicit doesn't work with SHARED?
Post by: bplus on August 12, 2019, 09:11:01 pm
Hi
I find logic the error pointed out by Option _explicit
why?
simple, we using SHARED  in closed block like SUB and FUNCTION to pass that inner variable to the main block.
But in the main block there is no definition of that variable which SHARED forced to be, so Option _Explicit does it work to show what is not declared explicitly.
To let work in different style Option _Explicit can give a warn and no halt the compilation because its goal is to give information to the user and not to correct the syntax.
What do you think about this?

Hmm... there is nothing declared in main to share with, what if there were? I will check it out.

Yeah, OPTION _EXPLICIT could give warning and then give option to proceed.
On the other hand, once OPTION _EXPLICIT has done it's job, it can be commented out before the run.

Title: Re: Option Explicit doesn't work with SHARED?
Post by: bplus on August 12, 2019, 09:35:59 pm
Aha! It woiked! The SHARED variable in the sub still needs a declared variable (with the same type) in the main.

Code: QB64: [Select]
  1. fooinit
  2. fooprint
  3. foolprint
  4.  
  5. SUB fooinit
  6.  
  7.     SHARED test AS INTEGER
  8.     test = 2
  9.  
  10. SUB fooprint
  11.     SHARED test AS INTEGER
  12.     PRINT test
  13.  
  14. SUB foolprint
  15.     DIM test
  16.     PRINT "The fool says test = "; test
  17.  
  18.  

Thanks again TempodiBasic!
Title: Re: Option Explicit doesn't work with SHARED?
Post by: SMcNeill on August 12, 2019, 09:50:12 pm
Aha! It woiked! The SHARED variable in the sub still needs a declared variable (with the same type) in the main.

But that defeats the whole purpose of using SHARED in subs/functions so you don’t need to declare the variables in the main module, for ease of library usage.

Seems silly to have to create a *.BI file just for DIM SHARED aVariable AS INTEGER, just because you have 2 SUBs which need to pass its value back and forth privately amongst themselves.

End in end, I guess I agree an awful lot with Rho’s accessment of the command — it’s not one I personally endorse or appreciate at all.  It’s honestly just a PITA which makes more work for folks who create libraries of their code.
Title: Re: Option Explicit doesn't work with SHARED?
Post by: bplus on August 12, 2019, 10:13:09 pm
Quote
But that defeats the whole purpose of using SHARED in subs/functions so you don’t need to declare the variables in the main module, for ease of library usage.

Well it is an option and it does not defeat the whole purpose of using SHARED in subs because part of the whole purpose is to not let other subs SHARE the variable, they are free to use the name and values for their purpose. And further, this is just not a part of the purpose, it is more like the main purpose of using SHARED in a sub.

More work? Well yeah, using OPTION _EXPLICIT forces you to DIM a hell of allot more things (everything) but that in turn forces you to think allot more about types the variable may declared.
As I recall "writing" a BI is merely a copy/paste from the source file it is tested in, really not that big a deal because OPTION _EXPLICIT has forced you to put it in main in first place.

If two subs are passing a variable and value back and forth, isn't it good to make note of that in something global like a BI file? It helps put things out in the open for users unfamiliar with the code to see and be aware of.

Title: Re: Option Explicit doesn't work with SHARED?
Post by: SMcNeill on August 12, 2019, 10:52:03 pm
Quote
If two subs are passing a variable and value back and forth, isn't it good to make note of that in something global like a BI file? It helps put things out in the open for users unfamiliar with the code to see and be aware of.

Why?  If it’s for internal use only, the user doesn’t need to be aware of it, or interact with it at all. 

A lot of times, you can code functions/subs so you normally wouldn’t need a *.BI file at all.  The SaveState and RestoreState functions I wrote are a perfect example.  When the first call is made to SaveState, it initializes a memblock to record up to 255 states to be saved.  RestoreState works with that shared memblock to restore those states when called.  Without someone using _OPTION EXPLICIT, they can be added to a single *.BM library and added into an user’s code.

What’s the advantage of requiring the user to have to add a COMMON SHARED, DIM SHARED, or DIM statement at the top of their code, just to avoid the OPTION _EXPLICIT error for a variable that’s only used internally within a library?

SUB foo
    SHARED whatever      <—— isn’t this, in fact, an explicit declaration of that variable?

If it’s not, then why is this valid:

SUB foo
    STATIC whatever

Why’s the word STATIC count as a valid declaration, but SHARED not?



Since people are using OPTION _EXPLICIT, SHARED is now a worthless command for SUB and FUNCTION.  May as well just DIM SHARED everything and force all libraries to come in two parts, rather than try to code and keep it simple so the end user only needs one *.BM file.
Title: Re: Option Explicit doesn't work with SHARED?
Post by: bplus on August 12, 2019, 11:04:39 pm
Quote
Since people are using OPTION _EXPLICIT, SHARED is now a worthless command for SUB and FUNCTION.  May as well just DIM SHARED everything and force all libraries to come in two parts, rather than try to code and keep it simple so the end user only needs one *.BM file.

Steve you are aware that you only have to DIM the variable in the main NOT DIM SHARED the variable in the main.

You are aware that using SHARED in a SUB and DIM in the main those are the only two places the scope goes.

SHARED is explained in WIKI as SHAREing exclusively with the main, the only way two procedures can SHARE the same variable is through the main procedure. No main procedure, no "private" sharing between procedures.

Something is worthless because you have to add a couple more words in a BI file? Sheesh!

BTW, STATIC is only sharing with itself, so it makes sense the dimensioning is finished inside the procedure.
Title: Re: Option Explicit doesn't work with SHARED?
Post by: SMcNeill on August 12, 2019, 11:27:18 pm
Something is worthless because you have to add a couple more words in a BI file? Sheesh!

It's not that you just have to add a few words to a BI file; it's that you have to sit down and make one, no matter what.  There's a lot of times when you could simply link one BM file, share it as a simple download, and have it handle everything with no issue, but with OPTION _EXPLICIT's behavior, you can't do that without causing issues for the users.  Now you need to make an extra BI file, package it together into a zip file, let the user download that, extract it, and then include both files in their code so they can make use of your procedures...

It's just a PITA, and I don't really see why it needs to be.  Guess I'm just glad I'm not an user of OPTION _EXPLICIT, and if somebody has issues with errors from a library they downloaded, they'll just have to muddle through and sort out the solution for themselves somehow.  It's not like it's really going to end up affecting me much in the long run anyway.  The only reason why I even became aware of the issue is where you posted about the behavior here: https://www.qb64.org/forum/index.php?topic=1593.msg108154#msg108154 ;)
Title: Re: Option Explicit doesn't work with SHARED?
Post by: SMcNeill on August 12, 2019, 11:44:21 pm
Taking a moment to dig into the source, it appears as if this behavior is intentional.

Open QB64.bas from the source folder.

Do a search for "shrfound:", and look up a few lines in the code.  (shrfound: is a label and thus unique in the code, and it's just below the relevant line to examine.)

The line you're wanting to examine is this one:
Code: [Select]
IF optionexplicit THEN a$ = "Variable '" + n$ + "' (" + symbol2fulltypename$(typ$) + ") not defined": GOTO errmes
Just remark it out, recompile, and then you're good to go.  OPTION EXPLICIT won't generate errors anymore when used to create a variable from inside a SUB.

And we *do* create a variable with SHARED, as we can see from the code directly above and below the IDE error call:
Code: [Select]
            'create variable
            IF LEN(s$) THEN typ$ = s$ ELSE typ$ = t$
            IF optionexplicit THEN a$ = "Variable '" + n$ + "' (" + symbol2fulltypename$(typ$) + ") not defined": GOTO errmes
            bypassNextVariable = -1
            retval = dim2(n$, typ$, method, "")
            IF Error_Happened THEN GOTO errmes
            'note: variable created!

QB64's internals consider SHARED to be a valid way to create and declare a variable.  (Which oddly enough, we can't create and SHARE an array the same way.  (IF a THEN a$ = "Array '" + n$ + "' not defined": GOTO errmes))

If QB64 recognizes SHARE as a valid means to create and declare a variable, why is there a need for OPTION _EXPLICIT to claim that it's not?
Title: Re: Option Explicit doesn't work with SHARED?
Post by: FellippeHeitor on August 13, 2019, 12:07:18 am
Quote
Taking a moment to dig into the source, it appears as if this behavior is intentional.

Yes.
Title: Re: Option Explicit doesn't work with SHARED?
Post by: bplus on August 13, 2019, 12:43:43 pm
Code: QB64: [Select]
  1. 'test foo libr load without BI
  2. fooinit
  3. fooprint
  4. foolprint
  5.  
  6. 'DIM test AS INTEGER
  7.  
  8. ' the error message tells me (The OPTION _EXPLICIT user) what is needed
  9. ' and it can be fixed without need of a BI file!!!!!!!!!!!!!!!!!!!!!!!
  10.  
  11. 'SUB fooinit
  12. '    SHARED test AS INTEGER
  13. '    test = 2
  14. 'END SUB
  15.  
  16. 'SUB fooprint
  17. '    SHARED test AS INTEGER
  18. '    PRINT test
  19. 'END SUB
  20.  
  21. SUB foolprint
  22.     DIM test
  23.     PRINT "The fool says test = "; test
  24.  
  25. '$include: 'foo libr.bm'
  26.  
  27.  

Error: but notice the message down below, it points to exactly what is needed
  [ This attachment cannot be displayed inline in 'Print Page' view ]  

Fixed wo need for BI include!
Code: QB64: [Select]
  1. 'test foo libr load without BI
  2. fooinit
  3. fooprint
  4. foolprint
  5.  
  6.  
  7. ' the error message tells me (The OPTION _EXPLICIT user) what is needed
  8. ' and it can be fixed without need of a BI file!!!!!!!!!!!!!!!!!!!!!!!
  9.  
  10. 'SUB fooinit
  11. '    SHARED test AS INTEGER
  12. '    test = 2
  13. 'END SUB
  14.  
  15. 'SUB fooprint
  16. '    SHARED test AS INTEGER
  17. '    PRINT test
  18. 'END SUB
  19.  
  20. SUB foolprint
  21.     DIM test
  22.     PRINT "The fool says test = "; test
  23.  
  24. '$include: 'foo libr.bm'
  25.  
  26.  

Fixed and runs without any BI file Include statement.
  [ This attachment cannot be displayed inline in 'Print Page' view ]  

Steve, a BI file is still not needed for SHARED variables in library code procedures.

It is up to the OPTION _EXPLICIT user to be aware that SHARED variables in library procedures or ported from tool box will need to be DIM in main or comment out OPTION _EXPLICIT.

It might be nice to add this warning to OPTION _EXPLICIT documentation.
Title: Re: Option Explicit doesn't work with SHARED?
Post by: SMcNeill on August 13, 2019, 01:01:46 pm
As long as somebody is going to add stuff to the wiki documentation, they might want to make a comment on the GIF creation page: https://www.qb64.org/wiki/GIF_Creation

The page has a GIFcreate.BM $INCLUDE file section that most likely isn’t going to work for anybody, ever.

Look at the demo code, and the very first line is DEFINT A-Z.  This line is required for the library to work properly, and it’s not placed down in the library itself...

Since QB64 defaults to SINGLE, the library will fail to work if just plugged into a program.  If a person DEFLNG (as is most common in modern programs, rather than DEFINT), the library fails.  And, if OPTION _EXPLICIT is placed at the top of the main program, the GIFcreate.BM generates about 50 errors one after the other, as there’s a ton of temp variables which aren’t declared.

It’s a rather old piece of code, and if it’s going to stay up in the wiki, it needs some serious reworking so folks can just copy, save it as a library, and then make use of it.
Title: Re: Option Explicit doesn't work with SHARED?
Post by: TempodiBasic on August 13, 2019, 04:12:20 pm
About this
Quote
On the other hand, once OPTION _EXPLICIT has done it's job, it can be commented out before the run.
I don't agree because
I think that its job is done only for the first variable not declared
Code: QB64: [Select]
  1. fooinit
  2. fooprint
  3.  
  4. SUB fooinit
  5.  
  6.     SHARED test AS INTEGER, test2 AS INTEGER, test3 AS STRING
  7.     test = 2
  8.     test2 = test^2
  9.     test3= str$(test2)
  10.     test4 = UCASE$(test3)
  11.  
  12. SUB fooprint
  13.     SHARED test AS INTEGER, test2 AS INTEGER, test3 AS STRING
  14.     PRINT test , test2 , test3 , test4

in fact if you add this line of code 
Code: QB64: [Select]
  1.  DIM test AS INTEGER
just before SUB section
you'll get the error/warning of OPTION _EXPLICIT for test2, and if you add, on following,
Code: QB64: [Select]
  1. DIM test2 AS INTEGER
you'll get the error/warning of OPTION _EXPLICIT for test3!
But if you REM out OPTION_EXPLICIT just for the first warning you loose the other warnings.
You can note that really test4 is never declared and it brings up a mismatch type error.
Title: Re: Option Explicit doesn't work with SHARED?
Post by: TempodiBasic on August 13, 2019, 04:27:14 pm
About this
Quote
using OPTION _EXPLICIT forces you to DIM a hell of allot more things (everything) but that in turn forces you to think allot more about types the variable may declared.
I think that stopping the compilation  this OPTION _EXPLICIT works with a Pascal spirit and not with a BASIC spirit.
IMHO in Pascal the absence of declaration is a syntax's error. So you first think, then declare and after type code.

in the end
this

Code: [Select]
IncreaseT
PrintT
END

SUB IncreaseT
SHARED t  AS INTEGER
t = t +1
END SUB

SUB PrintT
SHARED t AS INTEGER
PRINT  t
END SUB

is the implicit form of this one that follows

Code: [Select]
t = 0
IncreaseT
PrintT
END

SUB IncreaseT
SHARED t  AS INTEGER
t = t +1
END SUB

SUB PrintT
SHARED t AS INTEGER
PRINT  t
END SUB

so we can understand why OPTION _EXPLICIT claims declaration of variables, that are SHARED into SUB/FUNCTION, into main.
But in QB SHARED is the same? If so for backcompatibility with QB code OPTION _EXPLICIT must warn and not halt.

Thanks to read
Title: Re: Option Explicit doesn't work with SHARED?
Post by: SMcNeill on August 14, 2019, 06:35:51 am
Here's a tweak to QB64.bas which you guys might enjoy:

Code: QB64: [Select]
  1.                     IF optionexplicit THEN
  2.                         _CLIPBOARD$ = "DIM " + x$ + " AS " + symbol2fulltypename$(typ$)
  3.                         Give_Error "Variable '" + x$ + "' (" + symbol2fulltypename$(typ$) + ") not defined"
  4.                         EXIT FUNCTION
  5.                     END IF

SEARCH for IF optionexplicit, and then before any call to the error handler, insert a _CLIPBOARD statement, like the one above.   When QB64's IDE complains "Variable foo (INTEGER) not defined on Line ###", your clipboard with hold a statement of "DIM foo AS INTEGER", so all you have to do is paste it into your code inside the proper spot.  (Top of main code, inside the sub, wherever...)

It's a must learn trick, if you're going to be updating old code so it'll work properly without any OPTION _EXPLICIT error messages popping up.  ;)
Title: Re: Option Explicit doesn't work with SHARED?
Post by: bplus on August 14, 2019, 08:18:30 am
What an interesting idea! Thanks Steve