New items added 05/08/88 to 05/14/88: Part 1 - READ (QB 4) 2 - Watching a non-existant variable (Sample program #13) ------------------------------------------------------------------------- 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 -". 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 and The MicroHelp Toolbox. If you have additional information that should be added, please send it to: Mark Novisoff MicroHelp, Inc. 2220 Carlyle Drive Marietta GA 30062 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. 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 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). 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 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. 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 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. 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. 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. 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 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(-1) QB 4 If a Quick Library is loaded, this value may return incorrectly. QB 4 seems to forget that the library is loaded and thinks that the space is available. But, QB 4 won't let you use the space for dynamic arrays. 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 BRUN 57280 59912 BCOM 61560 61640 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* 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. 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; 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* If you use "ON ERROR GOTO 0", two problems can occur: 1. If an error occurs in your program, your system will crash. 2. You may get a "Program memory overflow" error from BC 4. 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. 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) 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. 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 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. RESUME All If you always use RESUME or RESUME