GLSL LINE Macro: Definition and Usage
The __LINE__ predefined macro in the OpenGL Shading
Language (GLSL) is a preprocessor directive that provides the current
source code line number as an integer during shader compilation. This
article explains the technical behavior of __LINE__, how it
changes during the compilation process, how developers can modify its
value using the #line directive, and its practical
applications in debugging and shader development pipelines.
What Information Does
__LINE__ Provide?
In GLSL, __LINE__ always expands to a decimal integer
constant representing the current line number within the shader source
string currently being processed. When the shader preprocessor
encounters the __LINE__ token, it replaces it with the line
number where that token resides.
Line numbering starts at 1 for the first line of the
source code and increments by one with each subsequent newline character
encountered during processing.
How __LINE__
Works During Compilation
Shader compilation in OpenGL occurs in stages, beginning with
preprocessing. Because __LINE__ is resolved by the
preprocessor:
- Static Replacement: It is replaced by an integer
literal before syntactic and semantic analysis take place. The GPU
execution unit never evaluates
__LINE__dynamically; its value is fixed at compile time. - Scope Across Multi-String Sources: When shaders are
supplied via multiple source strings (for instance, through the
glShaderSourceAPI call), the line count continues sequentially unless modified. However, GLSL also tracks the source string index via the__FILE__macro, which is an integer identifying which source string contains the current code.
Modifying
__LINE__ with the #line Directive
The behavior of __LINE__ can be manually altered using
the #line directive. This allows developers or build tools
to override the internal line counter:
#line 100
// The next line will evaluate __LINE__ as 100GLSL supports two forms of the directive:
#line line_numbersets the line number for the subsequent line toline_number.#line line_number source_string_numbersets both the line number and the source string index (which modifies__FILE__).
This directive does not alter the actual line count of the physical
file; it only overrides what the compiler and preprocessor report for
diagnostics and __LINE__ expansion.
Common Practical Applications
1. Mapping Generated Code to Original Files
In modern graphics engines, shaders are often constructed by
concatenating modular files, preambles, and generated template code. If
an error occurs, the compiler's line reporting points to the combined
file rather than the original source. By injecting #line
directives matching the original source locations, build systems ensure
that __LINE__ accurately reflects the line of the original
author's file.
2. Custom Debugging and Assertions
Developers frequently use __LINE__ alongside custom
macros to build diagnostic utilities or assertion handlers in GLSL:
#define ASSERT_VALID(condition) \
if (!(condition)) { /* Logic encoding __LINE__ into visual output */ }3. Error Tracking in Shader Translators
Tools that transpile high-level shading languages (such as HLSL or
Slang) into GLSL rely on __LINE__ to maintain precise
correlation between the target GLSL lines and the source language lines
during compiler diagnostics.