Pointer Restrictions in Core Desktop GLSL

Core desktop OpenGL Shading Language (GLSL) strictly disallows raw memory addresses, direct pointer arithmetic, and native reference types to ensure cross-platform execution safety and hardware portability. Instead of granting arbitrary memory access like C or C++, GLSL isolates shader execution through opaque types, controlled memory interfaces such as Shader Storage Buffer Objects (SSBOs), and value-result parameter passing. Understanding these architectural restrictions is essential for developers transitioning to shader programming from systems languages.

Prohibition of Address-of and Dereference Operators

Core desktop GLSL does not support the unary address-of (&) or dereference (*) operators. Memory is fully abstracted; variables represent symbolic entities allocated to registers or hardware-managed cache rather than visible, flat memory addresses. Consequently, developers cannot declare a type such as int* or store the memory location of any variable, struct, or array.

Function Parameter Passing via Value-Result

GLSL functions do not accept pointers or C++-style references (&). Instead, GLSL manages mutable function arguments through parameter qualifiers:

  • in (default): Values are copied into the function (pass-by-value).
  • out: Values are uninitialized upon entry, computed within the function, and copied back to the caller upon return.
  • inout: Values are copied into the function upon entry and copied back to the caller upon completion (copy-in/copy-out or value-result semantics).

Because the specification defines this behavior as copy-in/copy-out, changes made to an inout variable are not guaranteed to be immediately visible to other execution threads or aliased parameters during the execution of the function body.

Opaque Types for Resource Handles

External hardware resources, including textures, samplers, and image units, are represented as opaque types (e.g., sampler2D, imageBuffer).

  • No Address Extraction: Developers cannot obtain the memory address of an opaque resource or cast it to an integer or void pointer.
  • Restricted Passing: Opaque variables can only be passed into functions as in parameters. They cannot be returned from functions, instantiated as l-values, or modified.
  • Indexing Limitations: Dynamically indexing arrays of samplers is constrained depending on the GLSL version, requiring dynamically uniform expressions to prevent divergent memory access across warps/wavefronts.

Array Indexing Instead of Pointer Arithmetic

In C-based languages, arrays can be decayed to pointers and navigated using offsets. GLSL prohibits array decay:

  • Array variables evaluate directly to the aggregate array structure, not a pointer to the first element.
  • Navigation through contiguous memory must be performed strictly using the array subscript operator ([]).
  • Out-of-bounds indexing results in undefined behavior or hardware-defined clamp/drop behavior, without exposing adjacent variable memory to arbitrary reads or writes.

Absence of Dynamic Memory Allocation

Core desktop GLSL lacks heap allocation routines such as malloc, free, new, or delete. All variable lifecycles are bound to compile-time definitions:

  • Local variables exist purely within the scope of execution.
  • Structures and internal arrays must have sizes known at compile time (with the exception of unsized arrays appearing as the final member of a runtime-sized SSBO).
  • Memory cannot be recursively allocated, as recursive function calls are also strictly forbidden in core GLSL.

Memory Buffers and the restrict Qualifier

When arbitrary memory layouts are needed, core GLSL utilizes Shader Storage Buffer Objects (SSBOs). While SSBOs map to raw GPU buffers, core desktop GLSL treats them as structured interface blocks rather than pointer-accessible blocks of memory.

To manage hardware-level aliasing without true pointers, GLSL provides qualifiers such as restrict, coherent, readonly, and writeonly:

  • restrict: Informs the compiler that the specific buffer variable is not aliased with any other buffer or image within the same scope.
  • Unlike C99, where restrict is applied to pointer declarations, GLSL applies it strictly to interface block instances and image variables, enforcing access constraints directly at the binding level.