Part 1 - Updated for QB 4.50 -------------------------------------------------------------------------
This file contains information about bugs, quirks, and general points of interest to programmers working with compiled BASIC. It is divided into three parts:
Part 1 - Description of bugs, quirks, etc. Part 2 - General points of interest Part 3 - Sample programs
If you want to find one of the above quickly, use your text editor to search for the text shown above. i.e., Search for "Part 1 -".
As of 12/3/88, all new or changed entries will be marked with the date that the information as added or changed. The date will appear at the end of the entry in the format (yy/mm/dd).
This file is maintained by Mark Novisoff of MicroHelp, Inc. Much of the information was contributed by members of MicroHelp's BASIC Users Group, users of the MSSYS forum on Compuserve and users of Mach 2, Stay-Res, The MicroHelp Toolbox and the QB/Pro Professional series.
If you have additional information that should be added, please send it to: Mark Novisoff MicroHelp, Inc. 4636 Huntridge Drive Roswell GA 30075 Compuserve ID 73047,3706 in MSSYS (Microsoft Systems Forum)
If possible, please include a *small* sample program that will demonstrate the problem and cause it to happen whenever the program is run.
Part 1 - Description of bugs, quirks, etc.
Note: * Next to a QB 4 entry indicates that the problem has been fixed with the QB 4.00a that is included in BASCOM 6. The fix should apply to all later versions.
~ Next to a QB 4 entry indicates that the problem has been fixed in QB 4.00b (and the accompanying BC program).
` Next to a QB 4 entry indicates that the problem has been fixed in QB 4.50 and/or the accompanying BC program.
Command/Error Compilers Description -------------- --------------- -------------------------------------------- $INCLUDE QB 4 If you have a DEFINT statement in an include file and you wish to use it within subprograms/ functions in a module, you must $INCLUDE it within each sub/function structure. If you simply include it in the mainline code, the DEFINT statement is not recognized. However, if you have a statement DEFINT in your mainline code (as opposed to $INCLUDE), it will work ok. BLOAD/BSAVE QB 4~` When using these commands in DOS 2.x, you may get an unexpected "too many files" error. This problem can be solved using an assembly language routine to read/write the file. (Mach 2 users should use MhFile/MhRWSub). CALL (asm) QB 4 If you pass a static string array as a parameter to a subprogram, and the string array represents FIELDed data (as in a random file), AND you call an assembly subroutine that displays the data, your position in the file can be wiped out! See sample program #22. The fix is to place the string array in a COMMON SHARED statement and remove it from the parameter list. CALL QB 4 If you want to pass a single element from a string array to a subprogram, be sure to put an extra pair of parentheses around the variable name in the parameter list. For example, you may have a problem with: CALL MySub(A,B,C$(3),D) However, the following should work: CALL MySub((A,B,(C$(3)),D) CALL (asm) QB 4 Effective with QB 4, assembly language subroutines must preserve the SI and DI registers and make sure the direction flag is cleared before returning to BASIC. In addition, you must not have a label name after the END statement in your assembler code. CALL INIT QB 2-3 Do not name a precompiled subprogram "INIT". If you do, the compiler will go into never- never land when your user library is loaded. CALL INTERRUPT QB 4*` There is a bug in the source code (INTRPT.ASM). If you have MASM 5.0, you can patch the source code and reassemble. On line 49, the code points to the DI register with "-1EH". This should be changed to "-0EH", followed by reassembly and library updates. If you don't have MASM 5.0, the solution is to use INT86OLD, or you can patch INTRPT.OBJ as follows (all numbers are hexadecimal):
Address Old Value New Value ------- --------- ---------- 20E E2 F2 253 E2 F2 28D 0B EB CALL vs GOSUB All If you have many calls to the same asm routine or subprogram, you'll use less memory if you set variables and GOSUB to a routine that performs the CALL instead of having the CALL "in line". CALL is much faster using variables than using "literals". CALLS QB 4 If you are passing string arrays to an assembler subroutine, make sure that $Static is in effect (not $Dynamic) when you dimension your array. If you do not, the data are not pushed onto the stack correctly by BC. This affects the use of MhBasStringSort in Mach 2. CALLS QB 4* When CALLS (note the "S") is used and you compile with "/D" (debug), the segment of of a string element descriptor does not get passed on the stack. In other words, if you have an assembly language subroutine that uses CALLS, you should not compile with "/d". CHAIN QB 4~` Unreliable when using DOS 2.x. CIRCLE QB 4 The start and end angles must be LESS than 2*pi. Previously they could be less than or equal to. CLEAR QB 4 If you use SETMEM to free up memory for use by other routines or modules, the CLEAR statement does not force the compiler to give up that memory. In other words, you must explicitly do a SETMEM(640*1024), or other large number. (Also see RUN.) CLEAR,,Size QB 3,4 If you receive an out of stack space message. The stack size is not reset between CHAIN'ing but if you CHAIN back to your original program, be sure to skip the CLEAR instruction. COMMON and QB 2-4 All statements that use COMMON or variations COMMON SHARED thereon with CHAIN must use parameter lists that match exactly. Best done with $INCLUDE. COMMON with TYPE QB 4 The TYPE statement must appear before the COMMON statement and must appear in all programs that use it. The COMMON statement must contain "AS". See sample program #1 at the end of this file. Compile to EXE QB 4` QB issues an unusual LINK command in the form of: LINK Prog+YourLib.Lib; This causes LINK to bring the entire library into your program! The solution is to exit QB, and run BC and LINK yourself. Note also that the LIB environment variable is not used to search for libraries in this context, since the library name is in the object module field. CONST QB 4*~` Do not use string constants if you compile with the /s switch. See sample program #14. CONST QB 4 Must be included in all program modules that use the constant. Place in the file at the top, rather than inside SUB's. CVL QB 4*~` This function is unreliable when a program has been compiled with BC. See sample program #8. DATA QB 4 When a DATA statement is encountered inside a SUB...END SUB structure, QB moves it into the "mainline" portion of the code when you are in the environment. DEFINT QB 4 See $INCLUDE. DEF FN All Functions are local to the module in which the DEF FN appears. Use QB 4's FUNCTION..END FUNCTION for global functions. DEF SEG QB 4*~` See sample program #11. DIM QB 3 See sample program #4. QB3 apparently has a limit of 123 dynamic arrays. DIM QB 4 Any array that is DIMmed inside of a subprogram that does not have the STATIC keyword is a DYNAMIC array. DIM QB 4 In order to take advantage of the /AH switch with TYPE..END TYPE records, the record length must be a power of 2 (4,8,16,32, etc.) DIM QB 4 Static numeric arrays are stored on the "heap" when you are inside the QB 4 environment. BC programs store them in the default DS. DIM (TYPE) QB 4 See sample program #1 for dimensioning arrays of TYPE'd variables. Division All Using integer division "\" when an integer result is desired is much faster than normal division "/". DRAW QB 2-4 Does not respect the boundaries designated by WINDOW. Duplicate Definition QB 4 If you receive an otherwise unjustified "Duplicate definition" error, check to see if your program has variables called F$ or F%. When programs reach an undefined "critical mass" (in terms of size), variables using those names will cause the error. The solution is to find and replace all occurrences of those names with other names. (88/12/03) ENVIRON QB 2-4 If you attempt to create a new environment variable inside a program, you are likely to get an "out of memory" error, because the amount of environment space available when your program runs is very small. To get around this problem, create a good sized dummy variable in your AUTOEXEC.BAT, then inside your program, eliminate it before attempting to setup new variables. Eliminate the variable by using the semicolon: ENVIRON "DUMMY=;". ERR QB 4*~` Inside the QB 4 environment. If you watch a variable, ERR does not get set properly when an error occurs. See sample program #5. /FPA BASCOM 6 If you use the /FPA switch (alternate floating point math library) when compiling one or more modules, you must use the same switch in ALL modules in the same program. FIELD QB 4 We've had a report that if you use array elements for FIELD'ing a Btrieve file, and you don't DIM the string array (i.e., you default to 10 elements) that you can get string space corrupt errors. The solution is always to DIM the arrays. File not found All See KILL (Network). FILES QB 3 There is a bug in the QB3-8087 compiler that causes FILES not to work correctly. FOR/NEXT QB 4*~` If you pass a variable to a SUB, and that variable is used as a loop counter in a FOR/NEXT loop, the variable value is not returned to the main program. See sample program #15. Note that this happens only when compiled with BC - it works fine in the environment. FOR/NEXT QB 4*~` If you use a long integer as your loop counter, with a negative STEP, your loop will not execute. FOR/NEXT QB 4 If you use an integer for a loop counter, and the top of the loop is 32767 (when STEP is positive) or the bottom of the loop is -32768 (when STEP is negative), you'll get an overflow when inside the QB environment or when compiled with BC using "/d". With BC,if you don't use "/d", the loop does not stop at the top/bottom - it wraps around and executes your loop indefinitely. FRE("") QB 4* Using BRUN gives approximately 4K more than BCOM. Here is a table showing the difference between compilers for a one line program PRINT FRE(""):
BC BC6 BC(QB4.00b) BRUN 57280 59912 59912 BCOM 61560 61640 61640 FRE(-2) All Fre(-2) is unreliable in all versions of QuickBASIC 2-4. See sample program #26. FUNCTION QB 4 Provides global functions for all modules in a program. All that is needed is a DECLARE statement in any module that needs to use the function. In addition, this type of function can be recursive. See DEF FN. FUNCTION QB 4 Cannot be used in $INCLUDE files. GOTO QB 4` See sample program #17. GOTO QB 4* If you have a "GOTO GOTO" (two GOTOs) in your program, QB 4.00 goes into never-never land. You can still give a three-finger salute, though. HEX$ QB 4 Be careful when using with non-integer values. For example, the output from the two lines shown is "FFFF8002". E&=&H8002 PRINT HEX$(E&) IF..THEN..ELSE QB 3 More than two nestings for ELSE on a single line will not compiler properly. IF..THEN..ELSE QB 4 ` See Sample program #9. INPUT QB 4 ` Using INPUT directly to an array element that should generate a "subscript out of range" error causes a hard crash. LINE INPUT generates the error just fine. Note that this error occurs only inside the environment. See Sample program #10. Internal Error QB4` More problems with long integers. See sample in BC program #25. KILL (Network) All If you get a "file not found" error when attempting to KILL a file on a network drive, and you know the file exists, the problem is most likely due to the user not having "delete" rights in the network. In this case, the network will issue an "access denied" error, which BASIC will translate to "file not found". LEN QB 4*~` There is a problem using the LEN() function with user defined types. See Sample Program #12. LIB.EXE n/a LIB cannot recognize the name of a library if you precede the library name with a path that contains a hyphen "-". For example, if you enter the following, LIB will fail: LIB Test-Dir\MyLib LINE INPUT QB 4*~` Don't attempt to LINE INPUT directly to a typed variable (using TYPE...END TYPE) that has a period in the name. Rather, LINE INPUT to a temporary variable and then assign it to the TYPE'd variable. LINK All Use the /EXEPACK switch to condense the file. Can be used on any program except programs that are CHAIN'ed to using all compilers except QB 4. All QB 4 programs can use this switch. Syntax: LINK /EXE Progname (etc.) LINK QB 4 When building a Quick Library, be sure to specify BQLB40 in the library field. Example: LINK /QU ObjMods,Lib,,BQLB40; This also applies to BQLB41 if using BC6 or QB 4.00b and BQLB45 when using QB4.50. LOAD QB 4 If you receive an "out of memory" error, try breaking your program into logical pieces (using subprograms). Then use COMMON SHARED for all variables that you need in the entire program. The exact same COMMON SHARED declaration must appear in all the modules in the program that need access to the variables. LOAD QB 4 If you download a QB 4 program in "fast load" format, many modem transfer protocols pad the file out using a number of CHR$(0)'s. This will cause QB 4 to crash when you attempt to load the program. Use DEBUG to view the file, then write the program to disk after changing the CX register to shorten the length of the file so that the trailing CHR$(0)'s are not included. The other solution is to download this type of file using an ARC program that restores the original length of the file. ON ERROR QB 4*~` There is a problem with BC in QB 4.00 when you have ON ERROR inside of a subroutine (GOSUB type). See sample program #20. ON ERROR QB 4*~` If you use "ON ERROR GOTO 0", two problems can occur when compiled to an EXE program: 1. If an error occurs in your program, your system will crash. 2. You may get a "Program memory overflow" error from BC. ON ERROR QB 4 See "RESUME" for QB 4. ON ERROR QB 2-4 Error handler routines must be located outside SUB...END SUB structures. You can RESUME to a line number/label that is outside SUB...END SUB structures (using /E) or to code inside the sub using plain RESUME or RESUME NEXT (/X). Much better is to $INCLUDE subroutines that perform error trapping instead of having them in subprograms. This allows the use of RESUME line number/ label and avoids the /X. Note - with BASCOM 6 and QB 4.00b, error handling has been improved. See the docs. ON KEY QB 4*~` See sample program #16. If you use RETURN LineLabel in conjunction with a subroutine invoked by ON KEY, you can get a RETURN WITHOUT GOSUB error in the QB 4.00 environment. However, the program will work when compiled with BC. OPEN COM QB 4` If you compile with /S, and use OPEN COM with a literal string, the statement will generate "Device Unavailable". See sample program #18. OPEN COM QB 4*~` If you open the COM port within the environment, then compile to an EXE from within the environment, you get a "far heap corrupt" error. OPEN COM QB 4*~` If you open a COM port, close the port, then do a SHELL, you cannot reopen the same port. The compiler sets the COM port address (at hex 40:0 through 40:7, depending on the COM port number) to 0 and cannot find the port. The solution is to leave the port open during the SHELL. A fix is to save these addresses before opening any ports: DEF SEG=&H40 FOR I = 0 TO 7 PortAddress(I) = PEEK (I) NEXT DEF SEG After closing a port, do: DEF SEG = &H40 I = (PortYouOpened - 1) * 2 POKE I, PortAddress(I) POKE I + 1, PortAddress(I + 1) DEF SEG OPEN All With Novell NetWare, using OPEN on a file that does not exist does not always create the file. Novell has acknowledged the problem but they don't have a solution available as of 12/19/87. A workaround for the problem when using Btrieve is to open the NUL device on the local system instead of the network. For example, OPEN "R",1,"A:NUL". Overflow All BASIC uses integer types for all calculations and processes the right side of the equal sign before the left side. To force BASIC to use a different numeric type, place a type identifier on the right of the equal sign. Example: A=Peek(2)+256!*Peek(3) Periods in variable names QB 4 We have found numerous problems using periods in variable names. We believe the problems are somehow associated with TYPE..END TYPE user defined records. Because of these problems, we recommend that you do NOT use periods in variable names. See sample program #28 for one example of this problem. (88/12/03) PRINT # QB 4 In order to print a blank line using QB 4, use the syntax: PRINT #, Note the absence of the null string after the comma. We've had an unconfirmed report that if the print buffer is filled, using the null string causes characters to be dropped. PRINT USING QB 4 With previous compilers, you could place TAB statements, variable names, or most anything else between PRINT and USING. With QB 4, nothing should come between PRINT and USING. PUT 4.00b See sample program #21. When using the syntax PUT Filenumber,RecordNumber,Variable you'll get a "bad record length". READ QB 4` If you want a REMark on a line that contains DATA statements, be sure to put a colon on the line between the end of your data and the REM or '. REDIM QB 2.01 In EXE programs (not in the environment), the following logic will cause your FIELDed variables to go haywire:
REM $DYNAMIC DIM StringArray$(SomeNumber) FIELD #SomeFile.... ... ERASE StringArray$ REDIM StringArray$(ADifferentNumber) SomeVariable = FRE("")
The solution to the problem is to reFIELD the file after a REDIM and a FRE(""). REDIM QB 3 If you have a subprogram that REDIM's arrays, and you get a "string space corrupt" message after calling the subprogram several times, try using ERASE on the array before you do the REDIM. REM $INCLUDE QB 4` See sample program #24. REM $TITLE QB1-4 When you use the REM $TITLE metacommand, you are limited to 60 chars of title. If the title is longer, you'll get an error message "Metacommand error". Note that QB2.01 does not print an error message, but still shows "1 severe error". RESUME All If you always use RESUME or RESUME