TYPE and CONST within SUB/FUNCTION
#1
A while back I accidentally discovered that CONST can be used in SUBs and FUNCTIONs to create local constants. You can even use the same CONST variable name from the main code to create another unique local constant.

I was wondering if this worked with TYPEs. It appears it does not. While you can create a user defined TYPE within a SUB or FUNCTION it will always be seen globally. Is this correct behavior or should the user defined TYPE be local to the SUB and/or FUNCTION?

If the user defined TYPE is always to be seen globally then is it an oversight in the IDE to allow TYPEs to be created within a SUB or FUNCTION?

Code: (Select All)
OPTION _EXPLICIT

CONST SUB1_CONSTANT = 300 '      global everywhere unless also created within a subroutine
CONST SUB2_CONSTANT = 400

'TYPE Type_SUB1 '                if these lines are enabled an error occurs in SUB1()
'    a AS INTEGER
'    b AS INTEGER
'END TYPE

DIM Sub1_Variable AS Type_SUB1 ' Type_SUB1 is seen globally even though created in SUB1()
DIM Sub2_Variable AS Type_SUB2 ' Type_SUB2 is seen globally as well even though created in SUB2()

PRINT "-----------------"
PRINT "-- IN MAIN CODE -"
PRINT "-----------------"
PRINT "SUB1_CONSTANT  ="; SUB1_CONSTANT
PRINT "SUB2_CONSTANT  ="; SUB2_CONSTANT
PRINT
SUB1
SUB2

'----------------------------------------------------

SUB SUB1 ()

    CONST SUB1_CONSTANT = 100 '      constant is only local to this subroutine now

    TYPE Type_SUB1
        a AS INTEGER
        b AS INTEGER
    END TYPE

    DIM Sub1_Variable AS Type_SUB1 ' completely unique variable from one created at main code level

    PRINT "-----------------"
    PRINT "---- IN SUB1 ----"
    PRINT "-----------------"
    PRINT "SUB1_CONSTANT  ="; SUB1_CONSTANT
    PRINT "SUB2_CONSTANT  ="; SUB2_CONSTANT
    PRINT

END SUB

'----------------------------------------------------

SUB SUB2 ()

    CONST SUB2_CONSTANT = 200 '      constant is only local to this subroutine now

    TYPE Type_SUB2
        a AS INTEGER
        b AS INTEGER
    END TYPE

    DIM Sub2_Variable AS Type_SUB2 ' completely unique variable from one created at main code level

    PRINT "-----------------"
    PRINT "---- IN SUB2 ----"
    PRINT "-----------------"
    PRINT "SUB1_CONSTANT  ="; SUB1_CONSTANT
    PRINT "SUB2_CONSTANT  ="; SUB2_CONSTANT

END SUB
Software and cathedrals are much the same — first we build them, then we pray.
QB64 Tutorial
Reply
#2
TYPEs are always global, as per the odd behavior which QB45 had with them back in the day.

I think the reason was that some of the programmers back in those days used to write TYPE libraries and then just include them willy-nilly into the code whenever they needed them.  (Think of a TYPE point:  X AS INTEGER: Y AS INTEGER: END TYPE)  No matter where you put those type statements, they tend to produce global variable types for use.

And, honestly speaking, I'm not certain if you'd want it any other way.  Can you imagine the confusion of writing a library with a POINT type, and making it 2D, while someone else creates a library with a POINT type and makes it 3D?  If that's not a recipe for confusion and utter programming frustration, I don't know what would be!
Reply
#3
Quote:A while back I accidentally discovered that CONST can be used in SUBs and FUNCTIONs to create local constants. You can even use the same CONST variable name from the main code to create another unique local constant.

I was wondering if this worked with TYPEs. It appears it does not. While you can create a user defined TYPE within a SUB or FUNCTION it will always be seen globally. Is this correct behavior or should the user defined TYPE be local to the SUB and/or FUNCTION?
If a constant is declared within a procedure or function, it has the status "local" and is only known there. Otherwise a constant is declared globally; in the main program.

Type . . . End Type definitions can not be declared in functions or procedures; the best place for them is at the beginning of a program - right after the constant declaration.
Actually clear, because what's the point of a type declaration in a procedure or function?

However, type definitions can be used as argument types of procedures and functions.

From MS-DOS QBasic - The Technical Reference; The Wait Group 1991/92
Reply
#4
I am thinking, being able to Define a Type in a Sub or Function could be handy for Library Code might even save you from having to create a .BI file. Run an InitLibr sub to start Type(s) maybe?
b = b + ...
Reply
#5
(07-09-2023, 11:05 PM)Kernelpanic Wrote: Type . . . End Type definitions can not be declared in functions or procedures; the best place for them is at the beginning of a program - right after the constant declaration.
Actually clear, because what's the point of a type declaration in a procedure or function?

However, type definitions can be used as argument types of procedures and functions.

From MS-DOS QBasic - The Technical Reference; The Wait Group 1991/92
So perhaps the IDE accepting the creation of user defined TYPEs in SUBs and FUNCTONs is not desirable then. Should the IDE throw an error if TYPE ... END TYPE is used within a SUB or FUNCTION? I don't believe I've ever seen QBASIC/QuickBASIC 4.x code that used CONST or TYPE in a SUB or FUNCTION. KernelPanic's quote from the Qbasic tech reference seems to confirm at least that TYPE ... END TYPE was not allowed.

The weird behavior of CONST within in a SUB/FUNCTION got me thinking about all of this.

UPDATE: Ok, I fired up QuickBasic 4.5 and verified that you can indeed create TYPEs within SUBs and FUNCTIONs within the IDE and the IDE will even appear to use them as being global. However, when you try to compile it fails. TYPE ... END TYPE must be in the main program module.
Software and cathedrals are much the same — first we build them, then we pray.
QB64 Tutorial
Reply
#6
Good new code will be compatible with old but be more flexible for new stuff.
b = b + ...
Reply
#7
Example of connecting two string constants in the main program and a function (procedure works the same way).

Code: (Select All)
'Beispiel fuer Nutzung einer Konstanten in einer Funktion(Prozedur) - 10. Juli 2023

Option _Explicit

Declare Function satzErgaenzen(satz As String) as String

Const Stanislaw = "His conscience was clear, "

Locate 2, 3
Print "Konstanten verbinden in Hauptprogramm und Funktion"
Locate 3, 3
Print "=================================================="

Locate 5, 3
Print satzErgaenzen(Stanislaw)

End

Function satzErgaenzen$ (Stanislaw As String)

  Const Ergaenzen = "he never used it! -- Stanislaw Jerzy Lec"

  Stanislaw = Stanislaw + Ergaenzen
  satzErgaenzen = Stanislaw
End Function
Reply
#8
I would love to have local TYPEs rather than all of them be global.
Ask me about Windows API and maybe some Linux stuff
Reply
#9
(07-10-2023, 06:53 PM)SpriggsySpriggs Wrote: I would love to have local TYPEs rather than all of them be global.

I was hoping for the same thing when I went down this rabbit hole.
Software and cathedrals are much the same — first we build them, then we pray.
QB64 Tutorial
Reply
#10
Playing around with Types defined in Subs and Terry's test code, I switched to testing Type values and Shared with Main:
Code: (Select All)

Option _Explicit

Const SUB1_CONSTANT = 300 '      global everywhere unless also created within a subroutine
Const SUB2_CONSTANT = 400

'TYPE Type_SUB1 '                if these lines are enabled an error occurs in SUB1()
'    a AS INTEGER
'    b AS INTEGER
'END TYPE

Dim Sub1_Variable As Type_SUB1 ' Type_SUB1 is seen globally even though created in SUB1()
Dim Sub2_Variable As Type_SUB2 ' Type_SUB2 is seen globally as well even though created in SUB2()

SUB1
SUB2

Print "-----------------"
Print "-- IN MAIN CODE -"
Print "-----------------"
Print "Sub1_Variable.a  ="; Sub1_Variable.a
Print "Sub1_Variable.b  ="; Sub1_Variable.b
Print

'----------------------------------------------------

Sub SUB1 ()

    Const SUB1_CONSTANT = 100 '      constant is only local to this subroutine now

    Type Type_SUB1
        a As Integer
        b As Integer
    End Type

    Shared Sub1_Variable As Type_SUB1 ' completely unique variable from one created at main code level
    Sub1_Variable.a = 1
    Sub1_Variable.b = 2
    Print "-----------------"
    Print "---- IN SUB1 ----"
    Print "-----------------"
    Print "SUB1_Variable.a  ="; Sub1_Variable.a
    Print "SUB1_Variable.b  ="; Sub1_Variable.b
    Print

End Sub

'----------------------------------------------------

Sub SUB2 ()

    Const SUB2_CONSTANT = 200 '      constant is only local to this subroutine now

    Type Type_SUB2
        a As Integer
        b As Integer
    End Type

    Dim Sub2_Variable As Type_SUB1 ' completely unique variable from one created at main code level
    Sub2_Variable.a = 3
    Sub2_Variable.b = 4

    Print "-----------------"
    Print "---- IN SUB2 ----"
    Print "-----------------"
    Print "Sub2_Variable.a = "; Sub2_Variable.a
    Print "Sub2_Variable.b = "; Sub2_Variable.b

End Sub

Works as one might expect.
b = b + ...
Reply




Users browsing this thread: 2 Guest(s)