Q(uick)BASIC Function: VARPTR

Quick View

VARPTR and VARSEG

Memory functions that return the address of a variable

Worth knowing

Useful and cross-version information about the programming environments of QBasic and QuickBasic.

Syntax
  • VARPTR(variablename)
  • VARSEG(variablename)
Description/Parameter(s)
  • VARPTR returns the offset address of a variable.
  • VARSEG returns the segment address of a variable.

variablename Any Basic variable.
Syntax
  • VARPTR(variablename)
  • VARSEG(variablename)
Description/Parameter(s)

The variablename may be any BASIC variable, including a record variable or record element. The VARPTR function returns an unsigned integer that is the offset of the variable within its segment. The VARSEG function returns an unsigned integer that is the segment part of the variable's address. If variablename is not defined before VARPTR or VARSEG is called, the variable is created and its address is returned. When variablename is a string variable, VARPTR and VARSEG return the location of the first byte of the string descriptor.

Note: Because many BASIC statements change the locations of variables in memory, use the values returned by VARPTR and VARSEG immediately after the functions are used.

VARPTR and VARSEG are often used with BLOAD, BSAVE, CALL ABSOLUTE, CALL INTERRUPT, PEEK, POKE, or when passing arrays to procedures written in other languages.

When using VARPTR or VARSEG to get the address of an array, use the first element of the array as the argument:

  • DIM A(150)
  • ArrAddress=VARPTR(A(1))
Note: You may no longer use VARPTR to get the address of a file's buffer. Use the function FILEATTR to get information about a file.
In addition, programs written in earlier versions of BASIC that used VARPTR to access numeric arrays may no longer work. You must now use a combination of VARPTR and VARSEG. For example, the following QuickBASIC Version 3.0 fragment no longer works correctly:
  • DIM Cube(675)
  • BSAVE "graph.dat",VARPTR(Cube(1)),2700
The fragment would be rewritten as follows:
  • DIM Cube(675)
  • ' Change segment to segment containing Cube.
  • DEF SEG=VARSEG(Cube(1))
  • BSAVE "graph.dat",VARPTR(Cube(1)),2700
  • ' Restore BASIC segment.
  • DEF SEG

You may use VARPTR alone to get the address of a variable stored in DGROUP. You must use both VARPTR and VARSEG to get the complete address of a variable stored as a far object.

The VARSEG function, combined with VARPTR, replaces the PTR86 subprogram used in previous versions of QuickBASIC.

Example

For examples of how to use the VARPTR and VARSEG functions with other statements, seethe BSAVE and BLOAD programming examples,the CALL ABSOLUTE programming example, orthe CALL INTERRUPT programming example.This example program illustrates how to use the VARPTR and VARSEG functions in a CALL statement to pass a BASIC array to a C function.

'*** Programming example: VARPTR and VARSEG with CALL *** ' ' Do not attempt to run this program unless you have already ' separately compiled the C function with the large-model (/AL) ' switch and placed the object module in a Quick library or linked ' it to the BASIC main program. ' ' BASIC main program passing an array to C function. ' DEFINT A-Z ' DECLARE SUB AddArr CDECL (BYVAL Offs, BYVAL Segm, BYVAL Num) DIM A(1 TO 100) AS INTEGER ' Fill the array with the numbers 1 to 15. FOR I=1 TO 15 A(I)=I NEXT I ' ' Call the C function. AddArr expects a far address (segment ' and offset). Because CDECL puts things on the stack from ' right to left, put the offset ( VARPTR(A(1)) ) first in the ' list, followed by the segment ( VARSEG(A(1)) ). ' CALL AddArr(VARPTR(A(1)),VARSEG(A(1)),15%) ' ' Print the modified array. FOR I=1 TO 15 PRINT A(I) NEXT I END /* Add one to the first num elements of array arr.*/ void far addarr(arr,num) int far *arr; int num; { int i; for(i=0;i<num;i++) arr[i]++;
Syntax
  • VARPTR(variablename)
  • VARSEG(variablename)
Description/Parameter(s)
Variable type VARSEG returns VARPTR returns
Numeric Segment address of variable Offset address of variable
String Segment address of string descriptor descriptor Offset address of string
Name not previously defined Segment address of new variable (VARSEG also creates the new variable) Offset address of new variable (VARPTR also creates the new variable)

Usage Notes

  • When variablename is a numeric variable, the VARPTR function returns an unsigned integer (the offset of the variable within its segment).
  • When variablename is a numeric variable, the VARSEG function returns an unsigned integer (the segment address of the variable).
  • When variablename is a string variable, VARSEG returns the segment address of the variable, and VARPTR returns the offset address of The variable.
  • If variablename is not defined before VARPTR or VARSEG is called, the variable is created and its address is returned.
  • VARPTR and VARSEG are often used with ABSOLUTE, BLOAD, BSAVE, INTERRUPT, PEEK, POKE, or when passing arrays to procedures written in other languages.

Note on Mixed-Language Programming

  • Do not pass expanded memory arrays to non-BASIC procedures. (If you start QBX with the /Ea switch, any of these arrays may be stored in expanded memory:
    • Numeric arrays < 16K in size
    • Fixed-length string arrays < 16K in size
    • User-defined-type arrays < 16K in size
  • If you want to pass arrays to non-BASIC procedures, first start QBX without the /Ea switch. (Without the /Ea switch, no arrays are stored in expanded memory.)
  • For more information on using expanded memory, see Using Expanded Memory

Usage Notes

  • When using VARPTR or VARSEG to get the address of an array, use the first element of the array as the argument:
    • DIM A(150)
    • ArrAddress = VARPTR(A(1))
  • You can use VARPTR alone to get the address of a numeric variable stored in DGROUP. You must use both VARPTR and VARSEG to get the complete address of a numeric variable stored in far memory.
  • It is not meaningful to use VARSEG and VARPTR for far strings, since the format of the far strings' string descriptor is different from the string descriptor for near strings. See the StringAddress for routine information on locating the address of a far string's string descriptor.
  • You cannot use VARPTR to get the address of a file's buffer. Use the FILEATTR function to get information about a file.
  • Programs written in earlier versions of BASIC that used VARPTR to access numeric arrays may no longer work. You must now use a combination of VARPTR and VARSEG. For example, the following QuickBASIC version 3.0 fragment no longer works correctly:
    • DIM Cube(675)
    • BSAVE "graph.dat",VARPTR(Cube(1)),2700
  • The fragment could be rewritten as follows to work in the current version of BASIC:
    • DIM Cube(675)
    • ' Change segment to segment containing Cube.
    • DEF SEG=VARSEG(Cube(1))
    • BSAVE "graph.dat",VARPTR(Cube(1)),2700
    • ' Restore BASIC segment.
    • DEF SEG
  • The VARSEG function, combined with VARPTR, replaces the PTR86 subprogram used in previous versions of BASIC.

Programming With OS/2 Protected Mode

  • The VARSEG function returns the selector of the specified variable or array.

Important

  • Because many BASIC statements move variables in memory, use the values returned by VARPTR and VARSEG immediately after the functions are used.
Example

This example uses the VARPTR and VARSEG functions in a CALL statement to pass a BASIC array to a C function.
Note: To run this program, you must separately compiled the C function with the large-model (/AL) switch and place the object module in a Quick library or link it to the BASIC program.

DEFINT A-Z DECLARE SUB AddArr CDECL (BYVAL Offs, BYVAL Segm, BYVAL Num) DIM A(1 TO 100) AS INTEGER 'Fill the array with the numbers 1 to 15. FOR I = 1 TO 15 A(I) = I NEXT I 'Call the C function. AddArr expects a far address (segment and offset). 'Because CDECL puts things on the stack from right to left, put the offset, 'VARPTR(A(1)), first in the list, followed by the segment, VARSEG(A(1)). CALL AddArr(VARPTR(A(1)), VARSEG(A(1)), 15) 'Print the modified array. FOR I = 1 TO 15 PRINT A(I) NEXT I END '/* C Function AddArr */ '/* Add one to the first num elements of array arr.*/ 'void far addarr(arr,num) 'int far *arr; 'int num; '{ ' int i; ' for(i=0;i<num;i++) arr[i]++; '}