Q58108: BASIC 7.00 Wrong Integer FOR-NEXT Index Results in .EXE
Article: Q58108 Product(s): See article Version(s): 7.00 | 7.00 Operating System(s): MS-DOS | OS/2 Keyword(s): ENDUSER | SR# S900123-121 buglist7.00 fixlist7.10 | mspl13_basic Last Modified: 1-AUG-1990 In a compiled .EXE program, a FOR ... NEXT loop with an ending loop counter value that is a variable and with a body that contains an integer or long integer array assigned to a single- or double-precision value can PRINT an incorrect value for the loop counter. This problem occurs in a compiled .EXE program only, not in the QuickBASIC Extended environment (QBX.EXE). An example of this problem is shown in the program below. Microsoft has confirmed this to be a problem in Microsoft BASIC Professional Development System (PDS) version 7.00 for MS-DOS and MS OS/2. This problem was corrected in Microsoft BASIC PDS version 7.10. The program below illustrates two conditions that, when occurring together, can produce an undesirable effect. The root of this error is embedded in the BASIC compiler (BC.EXE) optimization techniques. The two conditions necessary to show this problem are as follows: 1. A variable (not a constant) is used as the stop (ending) loop counter value on a FOR ... NEXT statement. 2. An integer or long integer array (which is subscripted with the loop counter) is assigned to a single- or double-precision number. (This is known as "typecasting" -- a single- or double-precision number is typecasted to an integer or long integer.) The problem occurs only on the first PRINT statement in the source file that prints the loop counter (i%). For all loop iterations, that PRINT i% statement incorrectly displays the fixed value of t#, the ending loop value. PRINT i% statements farther down in the source code work correctly. To eliminate the problem, use one of the following workarounds: 1. Compile with the BC /X option. Note: In the example below, the debug compiler option (/D) does not correct the problem. 2. Use the CINT() function to convert the real number to an integer before assigning it to the integer or long integer array. 3. Use a numeric constant (instead of a variable) for the ending value of the FOR loop counter. 4. Compile with the BC /FPa option (instead of the default /FPi). Code Example ------------ Dim ia%(10) 'An integer or long array shows problem. t# = 5 't# can be any numeric type (!, @, #, %, or &) FOR i% = 1 to t# 't# is the ending value of the loop counter, i% PRINT i%; 'This value incorrectly prints equal to t# in .EXE ia%(i%) = 46.7 'A real number is typecast to an integer or 'long-integer value and assigned to the array REM ia%(i%) = CINT(46.7) 'Workaround: use CINT(46.7) in the above line. PRINT i%; 'This value prints correctly. PRINT ia%(i%) 'This value prints correctly. NEXT i% END Below is the (incorrect) output from this .EXE (compiled without BC /X): 5 1 46.7 5 2 46.7 5 3 46.7 5 4 46.7 5 5 46.7 The output should be as follows: 1 1 46.7 2 2 46.7 3 3 46.7 4 4 46.7 5 5 46.7
THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.
Copyright Microsoft Corporation 1986-2002.