Q32271: Passing Element of FIELDed Array to Subprogram UnFIELDs Array
Article: Q32271 Product(s): See article Version(s): 4.00 4.00b 4.50 Operating System(s): MS-DOS Keyword(s): ENDUSER | B_BasicCom | mspl13_basic Last Modified: 20-AUG-1990 The following information applies to QuickBASIC Versions 4.00, 4.00b, and 4.50, to Microsoft BASIC Compiler Versions 6.00 and 6.00b for MS-DOS and MS OS/2, and to Microsoft BASIC Professional Development System (PDS) Version 7.00 for MS-DOS and MS OS/2. Passing an element of a FIELDed array to a subprogram unFIELDs the array, preventing the array from accessing the random file buffer. QuickBASIC Versions 3.00 and earlier do not unFIELD the array and allow you to access the random file buffer. The program below works without modification in QuickBASIC Versions 3.00 and earlier. The program needs to be modified (to pass the array elements by value or by a temporary variable) in QuickBASIC Versions 4.00 and later because arrays are handled differently. For QuickBASIC Versions 4.00 and later, when an array element is passed to a subprogram or function, the array element is copied to a temporary variable and passed to the subprogram. Upon returning from the subprogram, the temporary variable value is assigned to the array element. This process is performed in case the array moves during the execution of the subprogram or function; it also "unFIELDs" the array. Please note that in all versions of BASIC, FIELDed variables are "special" and have limited use. For example, you are not allowed to say INPUT B$, where B$ is a FIELDed variable. You also cannot say B$="test" and must instead say LSET B$="test" or RSET B$="test". This change in how the arrays are handled may affect any program that uses FIELDed arrays, including those applications that use Btrieve (a file-management system developed by SoftCraft, Inc.; Btrieve was later taken over by Novell, Inc.). The easiest workaround is to pass a temporary variable instead of an array element in the CALL statement. Another workaround for this problem is to put parentheses around the variable being passed in the CALL statement, thus causing it to be passed by value rather than by reference. An array passed by value is not unFIELDed. For example, the Code Example farther below could be changed as follows: CALL TEST((a$(i))) However, a disadvantage of passing by value is that if variables are large (such as a large string length), they could consume stack space quickly, possible leading to "Out of Stack Space" or "Out of Memory". The following code example demonstrates the unFIELDing of the array A$(). DIM A$(2) OPEN "TEST.DAT" AS #1 FIELD #1, 10 AS A$(0), 10 AS A$(1), 10 AS A$(2) K = 65 FOR J = 1 to 2 FOR I = 0 TO 2 LSET A$(I)=STRING$(10,K) K = K + 1 NEXT I PUT#1, j NEXT J CLOSE #1 OPEN "TEST.DAT" AS #1 FIELD #1, 10 AS A$(0), 10 AS A$(1), 10 AS A$(2) FOR J = 1 to 2 GET#1, J FOR I = 0 to 2 CALL TEST(a$(i)) NEXT I print NEXT J END SUB TEST(b$) STATIC PRINT b$ END SUB The output is as follows: AAAAAAAA BBBBBBBB CCCCCCCC AAAAAAAA BBBBBBBB CCCCCCCC As a workaround, the following modification can be made to the program to receive the desired output: GET#1, J FOR I = 0 to 2 temp$=a$(i) CALL TEST(temp$) LSET a$(i)=temp$ NEXT I The correct output is as follows: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD EEEEEEEE FFFFFFFF
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.