01-29-2026, 02:31 PM
With v 4.4.0, QB64PE has finally adopted to the QB45 style of allowing users to put SUBS and FUNCTIONS anywhere inside their code.
This was something which QB45 and QBASIC always allowed, but the old IDE had a habit of moving subs to their own windows (if you guys remember), and then it saved them at the end of the code. You'd have to write code in EDIT or notepad or such, and then compile it from the command line so the IDE wouldn't move those subs/functions automagically on you, but it always has been a part of the language itself.
It's the reason why QB45 allowed you to use a single file for $INCLUDE libraries and not have to split your work into two files to separate into the top and the bottom of the code. Just one file at the top and you're good to go with $INCLUDE!
But there is something that folks need to be aware of, and keep in mind -- BASIC has certain commands and precompiler commands which run in a simple TOP TO BOTTOM format, so you can't think of it as the SUBs just being moved to the end of the code.
For example, let's take a look at the following code:
If you notice, the DEFINT is a TOP TO BOTTOM command. So is the $IF and $LET commands.
Even though we change the DEF *after* the sub, it does nothing to change the default variable types inside the sub.
Same with the $LET. Where the SUB is located in our code, the $LET isn't defined and thus defaults to FALSE. Even though we set the precompiler variable AFTER the sub, it's not going to have any affect upon the SUB itself -- even if we call the SUB afterwards.
DEF statements, _DEFINE statements, $CHECKING, $IF, $LET and other such commands work on a simple precompiler TOP TO BOTTOM format. Keep this in mind and don't think that you can $LET a variable after the SUB and have it affect the sub. It doesn't work like that.
If you're going to create libraries which rely on DEF statements or $IF conditions, the order of which your commands come is very important.
The above would carry the value of *foo* into the library.
Whereas the above here wouldn't. Make certain you guys don't get confused now that SUBS and such might be earlier in the code or in the libraries. Program flow is still as important as ever. It's just that where you place those SUB/FUNCTION statements has now become a lot more flexible than ever before.
This was something which QB45 and QBASIC always allowed, but the old IDE had a habit of moving subs to their own windows (if you guys remember), and then it saved them at the end of the code. You'd have to write code in EDIT or notepad or such, and then compile it from the command line so the IDE wouldn't move those subs/functions automagically on you, but it always has been a part of the language itself.
It's the reason why QB45 allowed you to use a single file for $INCLUDE libraries and not have to split your work into two files to separate into the top and the bottom of the code. Just one file at the top and you're good to go with $INCLUDE!
But there is something that folks need to be aware of, and keep in mind -- BASIC has certain commands and precompiler commands which run in a simple TOP TO BOTTOM format, so you can't think of it as the SUBs just being moved to the end of the code.
For example, let's take a look at the following code:
Code: (Select All)
Screen _NewImage(800, 600, 32)
DefInt A-Z
foo
Sub foo
Print Len(default_variable)
$If YEP Then
Print "Yep"
$Else
Print "Nope"
$End If
End Sub
Print
Print "And now we change the DEF and $LET precompiler values"
DefLng A-Z
$Let YEP = TRUE
Print "And let's see if anything has changed with how SUB foo behaves"
foo
Print
Print
Print "But let's see how things look after the change, if used in the main code."
Print Len(default_variable)
$If YEP Then
Print "Yep"
$Else
Print "Nope"
$End If
If you notice, the DEFINT is a TOP TO BOTTOM command. So is the $IF and $LET commands.
Even though we change the DEF *after* the sub, it does nothing to change the default variable types inside the sub.
Same with the $LET. Where the SUB is located in our code, the $LET isn't defined and thus defaults to FALSE. Even though we set the precompiler variable AFTER the sub, it's not going to have any affect upon the SUB itself -- even if we call the SUB afterwards.
DEF statements, _DEFINE statements, $CHECKING, $IF, $LET and other such commands work on a simple precompiler TOP TO BOTTOM format. Keep this in mind and don't think that you can $LET a variable after the SUB and have it affect the sub. It doesn't work like that.
If you're going to create libraries which rely on DEF statements or $IF conditions, the order of which your commands come is very important.
Code: (Select All)
$LET foo = TRUE
$INCLUDE:'My_Lib.BI'The above would carry the value of *foo* into the library.
Code: (Select All)
$INCLUDE:'My_Lib.BI'
$LET foo = TRUEWhereas the above here wouldn't. Make certain you guys don't get confused now that SUBS and such might be earlier in the code or in the libraries. Program flow is still as important as ever. It's just that where you place those SUB/FUNCTION statements has now become a lot more flexible than ever before.

