Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
A Question on Calls to Subroutines
#1
If I Dim Shared a variable or an array, if the main module does NOT make a call to a Subroutine, will the program flow check out the Sub for variables and or arrays that have been deemed Shared?? Or it's pretty safe to rely on the program never going to a Sub that is NOT called.
Reply
#2
DIM SHARED makes a variable completely global, everywhere in the program. Such a variable is not protected inside a subprogram, and much less inside a GOSUB subroutine.

Probably trying to force it local inside a subprogram by using STATIC creates a "Duplicate definition" error message. But I've been surprised before by this BASIC dialect.

Subprograms and other code that is not called will be added to the program while it's compiled. It will be part of the final EXE file or counterpart on Linux or MacOS. If you are somebody who cares a lot about executable file sizes then it's better to analyze which portions of the program are not being called and exclude them altogether. This is most noticeable with fonts, graphics and music support. If there's anything that looks like it calls upon loading a JPEG or WAV, or asks to set a different font, whether or not that subprogram or GOSUB subroutine is actually executed in your program, it will be involved in the final executable created by QB64PE.
Reply
#3
OK, I actually tested out the following code:

Code: (Select All)

DIM SHARED test AS LONG

test = 4
PRINT test
callthisthing test
PRINT test
PRINT "End of my tests!"
END

SUB callthisthing (u AS LONG)
STATIC test AS INTEGER
test = test + 1
u = u * 2
END SUB

First it prints 4 then 8. The "test" variable inside the subprogram is "protected", of type INTEGER which is two bytes. Although there is a variable named just like it which is supposed to be accessible inside that subprogram which is twice as large.

Without STATIC declaration line the second PRINT test would give 10.



On Spiral Linux KDE (Debian "Bullseye" clone), I compile this program:

Code: (Select All)

SCREEN _NEWIMAGE(640, 480, 12)
setmyfont
PRINT "Print this for me in different letters!"
END

SUB setmyfont ()
DIM afont AS STRING, han AS LONG
afont = "/usr/share/fonts/truetype/liberation/LiberationMono-Regular.ttf"
han = _LOADFONT(afont, 24)
_FONT han
END SUB

to get this executable file:

Code: (Select All)
-rwxr-xr-x 1 fc fc    1734368 Nov 22 16:33 nd22-2

Commenting out "setmyfont" line just below SCREEN statement will not do anything about it. Must remove "setmyfont" call and definition entirely from the program, if that's the only thing that will have anything to do with fonts.
Reply
#4
Thanks MNR..

 so a Dim Shared variable or array, once created will carry a value of zero. That value can not change unless there is a routine or subroutine somewhere in the programs code to change it. IF the variable or array is created locally within a subroutine, shouldn't there be an error for a non exiting entity if the main module tries to use it?

For example

 Dim Shared A As Integer
Print A
Print B
TestB


Sub TestB
    Dim B
    B = 1

End Sub

In the above code only the variable A was created in the main module. The B variable is not created until the subroutine is called. So the command to Print B before it is actually created, shouldn't that trigger an error?
Reply
#5
In QuickBASIC and QBasic, this program must work, and it does. "B" is declared silently by the interpreter/compiler AS SINGLE.

Add OPTION _EXPLICIT at the top and it becomes a QB64 program that won't compile, for the reason you have provided. The "B" inside the subprogram is not the same as the "B" in main-level code. You could see this for yourself, changing the places of "TestB" subprogram call with printing out the global variable "B".
Reply
#6
Option _Explicit  - who knew - thanks again
Reply
#7
(11-23-2023, 01:53 PM)Dimster Wrote: Option _Explicit  - who knew - thanks again

IMHO, never write a program without OPTION _EXPLICIT as the first line of your code.

Lesson 2 explains it here.
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Reply
#8
Quote:@mnrvovrfc - First it prints 4 then 8. The "test" variable inside the subprogram is "protected", of type INTEGER which is two bytes. Although there is a variable named just like it which is supposed to be accessible inside that subprogram which is twice as large.

Without STATIC declaration line the second PRINT test would give 10.
Something is unclear there.  Huh

Call by reference:
Code: (Select All)

'A little problem Wink - 24. Nov. 2023

Option _Explicit

Declare Sub callthisthing (u As Long) As Long

Dim Shared test As Long

test = 4
Print " test 1  = "; test ' = 4

'Call by reference (Standard)
callthisthing test '= 1 -- First call!

'Because the procedure now receives the actual address
'of the variable and can change its value.
'The name in the procedure doesn't matter: u(test2) = 8
Print " test 2  = "; test ' = 8

Print
Print "End of my tests!"
End

Sub callthisthing (u As Long)

  Static As Integer test

  test = test + 1 ' = 1 -- (0 + 1)
  Print " Sub test = "; test

  u = u * 2
  Print " Sub u    = "; u ' = 8
End Sub

[Image: Call-by-reference-2023-11-24-192312.jpg]

Call by value:
Code: (Select All)

'A little problem Wink - 24. Nov. 2023

Option _Explicit

Declare Sub callthisthing (u As Long) As Long

Dim Shared test As Long

test = 4
Print " test 1  = "; test ' = 4

'Call by value
callthisthing (test) '= 1 -- First call!
Print " test 2  = "; test ' = 4 -- Because the procedure only worked with one copy.

Print
Print "End of my tests!"
End

Sub callthisthing (u As Long)

  Static As Integer test

  test = test + 1 ' = 1 -- (0 + 1)
  Print " Sub test = "; test

  u = u * 2
  Print " Sub u    = "; u ' = 8
End Sub

[Image: Call-by-value-2023-11-24-192550.jpg]
Reply
#9
(11-23-2023, 01:28 PM)Dimster Wrote: Thanks MNR..

 so a Dim Shared variable or array, once created will carry a value of zero. That value can not change unless there is a routine or subroutine somewhere in the programs code to change it. IF the variable or array is created locally within a subroutine, shouldn't there be an error for a non exiting entity if the main module tries to use it?

For example

 Dim Shared A As Integer
Print A
Print B
TestB


Sub TestB
    Dim B
    B = 1

End Sub

In the above code only the variable A was created in the main module. The B variable is not created until the subroutine is called. So the command to Print B before it is actually created, shouldn't that trigger an error?
Why don't you try it?

[Image: I-say-Captain-2023-11-25.jpg]

He said captain
I said wot

He said captain
I said wot

He said captain
I said wot

He said captain
I said wot d'ya want  Tongue

Reply
#10
The "B" in the main program is of course zero. . . because the variable was not initialized. - Every variable in QuickBasic is basically zero until it is initialized with a value.

So the global A + B are zero. The B in the procedure, on the other hand, was initialized and in this case correctly results in 1.

[Image: I-say-Captain2-2023-11-25.jpg]
Reply




Users browsing this thread: 1 Guest(s)