VARPTR(variable)pb_cg_emit_varptr_builtin (pb_codegen.c:4140)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).
| Parameter | Description |
|---|---|
variable | Any variable: numeric (LONG, WORD, BYTE, INTEGER, QUAD, SINGLE, DOUBLE, CURRENCY), STRING, fixed-length string, array, or UDT structure. |
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.
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
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
LEA (Load Effective Address) to compute the RBP-relative address. This is a single instruction with no memory dereference.VARPTR simply loads that address value. No LEA needed.LEA with a linker-resolved label. The address is fixed at link time.pb_cg_emit_array_address, which handles bounds checking and base+offset arithmetic. VARPTR returns the computed element address.char* — use STRPTR instead.