Part 1 PAINT (QBX/BC7) PRINT CHR$(128) QB 4.50 RESTORE QB 4/BC6 Part 2 BC7 Type coercion from floating point to integer -------------------------------------------------------------------------
This file contains information about bugs, quirks, and general points of interest to programmers working with compiled BASIC. It is divided into four parts:
Part 1 - Description of bugs, quirks, etc. Part 2 - General points of interest Part 3 - Sample programs Part 4 - Video adapters compatible with QB 4.50
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 in the entry in the format (yy/mm/dd).
As of 2/8/89, all references to problems with QB4.00 and QB4.00a have been removed from this file. It is presumed that all QB programmers have upgraded either to QB4.50 or QB4.00b. If you are still using QB4.00 or 4.00a, call Microsoft at 206-454-2030 and ask for a free upgrade to 4.00b. If you are using BASCOM 6, there is a similar upgrade available to BASCOM 6.00b.
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: QB 4 under "Compilers" refers QB4.00b and 4.50.
` Next to a QB 4 entry indicates that the problem has been fixed in QB 4.50 and/or the accompanying BC program.
* Next to an entry indicates that the problem has been fixed in QBX and/or the accompanying BC 7.0 program.
Command/Error Compilers Description -------------- --------------- -------------------------------------------- $INCLUDE All If the last line of your $INLUDE file does not have a carriage return/line feed pair, spurious errors can occur! $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 All When running on an XT with SMARTDRV.SYS, you may find that the BLOAD will display only the first two screen lines. If so, removing SMARTDRV.SYS will solve the problem. (89/12/22) BLOAD All In order to BLOAD a file, the file must have been previously BSAVEd so that the 7 byte "header" is present. Although it may be possible to BLOAD files that were not saved with this header, it is dangerous because BASIC presumes that the header is there and will not load the first 7 bytes into memory. (89/03/31) 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.
Added (88/12/19). Even if the string array is NOT a FIELDed array, the data can become corrupt. The new solution is to move all CALL or CALLS statements that have string arrays as parameters to the MAIN program and remove them from SUBs. 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+/BC6+ 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 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 QB4/BC6* CHAINing from a small .EXE to a large .EXE can cause unpredictable problems. This has been corrected in QB 4.50. (89/07/29) CHAIN BC6.0x* If you are using extended runtime libraries, there are known problems with CHAIN. This includes problems in COMMON SHARED data. (89/07/29) CHAIN BC6.0x BC7.0 Contrary to the docs, the stack size is *not* preserved across a CHAIN. The workaround is to use the /ST:xxxx switch when LINKing your programs. (89/07/29) CHAIN QB 4, QB 3 & CHAIN and RUN will work correctly in DOS 2.1 BASCOM 6 when you compile with the BRUN library. They will not work correctly on the second CHAIN or run attempt if you compile with the BCOM library (/O). You will get one of the following errors: Out of memory, EXE failure, or Error R6005. (89/04/24) CINT QB 4/QBX If the number you want to convert is exactly halfway between two integers (i.e., .5), the rounding is done incorrectly when the number that would normally be the result is an odd number. See example program #30. (89/01/03) It turns out that this works exactly as Microsoft designed it - for statisticians. If the whole portion of the number is odd, the number is rounded up. If the whole portion is even, the number is rounded down. (89/11/03) CIRCLE QB 4/QBX The start and end angles must be LESS than 2*pi. Previously they could be less than or equal to. CLEAR QB 4/QBX 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.) Added 89/02/08: If you have an assembler routine that has allocated memory from the pool created by SETMEM (Mach 2's huge string arrays, for example), using SETMEM(640*1024) will still not release the memory. That's because the underlying program has may have done its own allocation of memory via DOS. In this case, you must force the assembler routine to free up the memory. In the case of Mach 2's huge string arrays, this is done by telling Mach 2 to release the memory. CLEAR,,Size QB 3,4/QBX If you receive an out of stack space message. The stack size is reset between CHAIN'ing but if you CHAIN back to your original program, be sure to skip the CLEAR instruction. Added 89/02/08: This is very important in QB4 if you have recursive subprograms and/or functions. "Recursive" means that the procedure can be invoked from inside the procedure. COMMON and QB 2-4/QBX 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/QBX 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* Must be included in all program modules that use the constant. Place in the file at the top, rather than inside SUB's. DATA BC4.00b/6.00b* See READ DATA QB 4/QBX 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. DECLARE QB 4/QBX QB4 allows you to use a procedure name as a label. See example program #32. (89/02/10) DEFINT QB 4 See $INCLUDE. DEF FN All These functions cause temporary strings to be held in memory. See example program #36. (89/10/10) 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. Device Unavailable (QB4+) This error has been reported, especially when using a fast machine (such as a 386), even though the device is present. The problem appears to be a matter of timing. The solution is to use error trapping and if "Device Unavailable" occurs, retry the OPEN statement three or more times. (90/01/19) DIM QB 3 See sample program #4. QB3 apparently has a limit of 123 dynamic arrays. DIM QB 4/QBX Any array that is DIMmed inside of a subprogram that does not have the STATIC keyword is a DYNAMIC array. DIM QB 4/QBX 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/QBX Static numeric arrays are stored on the "heap" when you are inside the QB environment. BC programs store them in the default DS. DIM (TYPE) QB 4/QBX 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) Added 89/02/08: These variable names can also cause "FUNCTION not defined" errors. ENVIRON QB 2-4/QBX 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=;". Error R6005 See CHAIN (QB 4) (89/04/24) EXEC Failure See CHAIN (QB 4) (89/04/24) Expression Too Complex QB 4.50/BC7 QB will generate this error if you try to concatenate more than 19 expressions. BC will do the same, but it may point to the wrong line. Specifically, if the BC4.5 compiler gives you this error, check the line *above* the indicated line. You may even get this error when the offending line has been REMmed. (89/07/29) This problem has been fixed in QBX, but still exists in BC 7.0. Far heap corrupt QB 4 When working in the environment, this error can occur when you are *saving* a file that uses several user-defined types and arrays in COMMON. (89/03/31) /FPA BASCOM 6/7 If you use VAL on a string "E9999" (or a similar string with a leading "E") and you compile with /FPA, you'll get an overflow error. Compiling without /FPA yields a VAL of zero. (89/03/31) /FPA BASCOM 6/7 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. Fixup Overflow BASCOM 6 If you include the Microsoft mouse object module (MOUSE.OBJ) in an extended runtime library, you will get a fixup overflow error. There are two solutions: Put MOUSE.OBJ in your program instead of the ERL, or use an alternate set of mouse routines, such as those in MicroHelp's QB/Pro Volume 4. (89/03/31) FOR/NEXT QB 4/BC7 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(-2) All Fre(-2) is unreliable in all versions of QuickBASIC 2-4. See sample program #26. The BC 7.0 documentation explains this. (89/11/03) 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/QBX/BC7 Cannot be used in $INCLUDE files. GOTO QB 4` See sample program #17. HEX$ QB 4/QBX/BC7 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 compile 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. INSTR BC 4.x See Sample Program #37. (89/10/12) INT QB 4/QBX/BC7 See Sample Program #29. (88/12/19) Internal Error QB 4` 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". 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 All* LINE does not respect the boundaries set with VIEW if you draw a filled box with LINE. See sample program #38. LINK with /PAC See sample program #31. Note that the /PAC switch is supported only by the latest versions of LINK. (89/02/10) 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/BC7. All QB 4/BC7 programs can use this switch. Syntax: LINK /EXE Progname (etc.) LINK QB 4 When building a Quick Library, be sure to specify BQLB4x 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. Similarly, with QBX use QBXQLB. LOAD QB 4/QBX/BC7 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. LOCK QB 4 If you LOCK records, then perform a SHELL, then you try to UNLOCK the same records, you may get a "permission denied" error (error 70). (88/12/19) LPRINT QB 4.50* See TAB with REDIM (QB 4.50) 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. BC7 has "ON LOCAL ERROR", which is even better. 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 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". Out of memory QB 4 BASCOM 6 See CHAIN (QB 4) 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) PAINT QBX/BC7 PAINT can't handle a CHR$(0). See Sample program #3. (90/02/17) 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 CHR$(128) QB 4.50 If you have a program that contains a PRINT "" and you save it in "fast load" format, BC4.50 will not compile it. The solution is to save your programs in text format. (90/02/20) PRINT QB 4.50* See TAB with REDIM (QB 4.50) PRINT All Try this program in QB: (89/02/10) FOR N = 29 TO 31 PRINT N, CHR$(N) NEXT The number "N" will print just fine, but the characters will not. In order to display these characters, use an assembler subroutine, such as MhScr in Mach 2. PRINT # QB 4 In order to print a blank line using QB 4, use the syntax: PRINT #n, 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/BC7 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/BC7 See sample program #21. When using the syntax PUT Filenumber,RecordNumber,Variable you'll get a "bad record length". Added 89/10/07 - see sample program #21 for another solution. READ BC4.00b & 6.00b* RUN does not do an implicit RESTORE. See Sample program #34. (89/07/29) 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/BC7 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". RESTORE QB 4/BC6 If you have two object modules with the same name (for example, one compiled from TEST.BAS and one from TEST.SUB), and you use RESTORE, and you get an error (or the wrong data) when you use READ, use the '$MODULE metacommand to give one of the modules a different name as far as LINK is concerned. Example: '$Module: 'TEST2' (90/02/26) RESUME All If you always use RESUME or RESUME