VARPTR

Syntax

Syntax: VARPTR(variable)
Source: pb_cg_emit_varptr_builtin (pb_codegen.c:4140)

Description

Returns the memory address of any variable. For numeric variables (LONG, WORD, BYTE, SINGLE, DOUBLE, etc.), this is the address of the value itself. For STRING variables, this returns the address of the string descriptor, not the string data (use STRPTR for the character data pointer). For arrays, it returns the address of the array descriptor. For UDT (TYPE) variables, it returns the address of the structure.

VARPTR is essential for low-level memory operations, calling DLL functions that require pointers to variables (e.g., BYREF parameters in C), implementing data structures, and interfacing with hardware or memory-mapped I/O.

The critical distinction from STRPTR: VARPTR(str$) = address of the descriptor (internal handle); STRPTR(str$) = address of the character data (the char* a C function expects).

Parameters

ParameterDescription
variableAny variable: numeric (LONG, WORD, BYTE, INTEGER, QUAD, SINGLE, DOUBLE, CURRENCY), STRING, fixed-length string, array, or UDT structure.

Return Value

A DWORD (32-bit) or QUAD (64-bit) memory address of the variable. For stack locals, this is a stack address (RBP-relative). For STATICs, this is a data section address.

Example

FUNCTION PBMAIN() AS LONG
    LOCAL x AS LONG
    LOCAL y AS SINGLE
    LOCAL s AS STRING
    LOCAL p AS DWORD
    
    x = 42
    p = VARPTR(x)                ' p = stack address of x
    PRINT "Address of x: "; p
    PRINT "Value at address: "; PEEK(LONG, p)
    
    ' Singe-precision float
    y = 3.14
    p = VARPTR(y)                ' p = stack address of y
    PRINT "Address of y: "; p
    
    ' STRING: VARPTR vs STRPTR
    s = "Hello World"
    p = VARPTR(s)                ' p = address of string descriptor
    PRINT "VARPTR(s) = descriptor at: "; p
    p = STRPTR(s)                ' p = address of character data
    PRINT "STRPTR(s) = data at:    "; p
    
    ' Modify a variable through its pointer
    x = 100
    p = VARPTR(x)
    POKE LONG, p, 200            ' x is now 200
    PRINT "x after POKE: "; x    ' prints 200
    
    ' Pass variable address to DLL functions
    ' DECLARE FUNCTION GetSystemMetrics LIB "user32.dll" _
    '     ALIAS "GetSystemMetrics" (BYVAL nIndex AS LONG) AS LONG
    ' LOCAL result AS LONG
    ' result = GetSystemMetrics(0)    ' by value
    '
    ' For BYREF parameters: use VARPTR
    ' DECLARE FUNCTION SomeAPIFunc LIB "some.dll" _
    '     (BYREF outValue AS LONG) AS LONG
    ' SomeAPIFunc(VARPTR(result))
    
    ' Array element address
    DIM arr(10) AS LONG
    arr(5) = 999
    p = VARPTR(arr(5))           ' p = address of arr(5)
    PRINT "arr(5) value: "; PEEK(LONG, p)
    
    FUNCTION = 0
END FUNCTION

Generated Assembly

Source: pb_cg_emit_varptr_builtin (pb_codegen.c:4140)
; Stack local: LEA for address
lea    rax, [rbp - var_offset]

; BYREF parameter: already an address
mov    rax, [rbp - param_offset]

; STATIC/GLOBAL: LEA for static label
lea    rax, [static_label]

; Array element: compute element address
mov    rax, r11                         ; from pb_cg_emit_array_address

Notes