GLSL User Variable gl_ Prefix Restrictions
The OpenGL Shading Language (GLSL) enforces strict identifier naming
rules to prevent namespace collisions between user code and internal
system functionality. Specifically, declaring any user variable or
custom identifier starting with the gl_ prefix is
prohibited by the language specification and results in a compilation
error. This article explains the exact rules governing the
gl_ prefix in GLSL, the scope of these restrictions, and
the standard conventions developers should use instead.
The Core Language Restriction
According to the official GLSL specification, all identifiers
starting with gl_ are strictly reserved for use by the
OpenGL system. This reservation covers the global namespace, local
variables, function names, structure types, structure field names,
interface blocks, and uniform block names.
If a shader author declares an identifier such as:
vec4 gl_CustomPosition; // Illegal
float gl_myVariable = 1.0; // Illegal
void gl_calculateLighting() {} // IllegalThe shader compiler will reject the code and output a compile-time error. The compiler treats these declarations as illegal attempts to redefine or declare unauthorized built-in system symbols.
Extent and Preprocessor Rules
The restriction applies universally across all shader stages, including vertex, fragment, geometry, tessellation, and compute shaders.
- Case Sensitivity: GLSL is case-sensitive. While
gl_is reserved for language-defined variables and functions, prefixes such asGL_are reserved for preprocessor macros and implementation-specific definitions. Defining macros or variables starting withGL_or containing double underscores (__) is similarly prohibited or leads to undefined behavior. - Struct and Interface Members: The restriction
extends beyond top-level variables. You cannot use the
gl_prefix inside struct declarations or uniform interface blocks:
struct Light {
vec3 gl_Color; // Illegal
};- Built-in Redeclaration Exceptions: The only
circumstance under which a shader may write an identifier starting with
gl_is when redeclaring certain built-in variables according to explicit specification allowances. For instance, in desktop GLSL, users may redeclare built-in arrays (such asgl_ClipDistance) to size them, or redeclare built-in interface blocks (likegl_PerVertex) to alter invariant qualifiers or compatibility settings. This is limited strictly to re-qualifying pre-existing system symbols, not declaring new ones.
Recommended Alternatives
To avoid conflicts with the implementation namespace, shader developers should adopt distinct naming conventions for user-defined identifiers. Common industry conventions include:
- Prefixing by storage qualifier: Using
u_orufor uniforms (e.g.,u_ModelViewMatrix),v_orvfor stage-to-stage varyings (e.g.,v_TexCoord), anda_orin_for vertex attributes. - Standard casing: Utilizing standard camelCase or
snake_case without the leading
gl_token (e.g.,customPositionorworld_space_normal).
Adhering to these standard conventions ensures cross-platform compiler compatibility across diverse GPU hardware vendors and driver implementations.