How the GLSL FILE Macro Identifies Source Strings

The __FILE__ macro in the OpenGL Shading Language (GLSL) preprocessor uniquely identifies shader source segments by expanding to a decimal integer constant rather than a text filename. Because the OpenGL API allows shaders to be assembled from an array of separate text strings, the preprocessor uses this integer to represent the zero-based index of the specific source string currently being parsed. This mechanism allows developers and compilers to trace compile-time errors and warnings back to their exact source origin within multi-part shaders.

Integer Evaluation Instead of String Literals

In standard C and C++, the __FILE__ macro expands to a string literal containing the name or path of the current source file (e.g., "main.cpp"). In GLSL, string literals are largely unsupported by the core language and its preprocessor. Consequently, the GLSL specification defines __FILE__ as a decimal integer indicating the source string number.

Mapping to glShaderSource

When passing source code to the GPU via the OpenGL API, developers typically use the glShaderSource function:

void glShaderSource(GLuint shader, GLsizei count, const GLchar **string, const GLint *length);

The count parameter specifies the number of individual strings contained in the string pointer array. The GLSL preprocessor sequentially compiles these strings as a single compilation unit, assigning an automatic index to each:

  • The first string in the array (index 0) has __FILE__ evaluated to 0.
  • The second string in the array (index 1) has __FILE__ evaluated to 1.
  • Subsequent strings increment this value sequentially (2, 3, ..., count - 1).

If a syntax or compilation error occurs, the shader compiler references this value in its error log, typically formatting diagnostic messages as 0(15) : error ... or ERROR: 0:15: ..., where the first number corresponds to the __FILE__ index and the second corresponds to the __LINE__ number.

Manipulating __FILE__ with the #line Directive

The behavior of __FILE__ can be manually overridden using the #line preprocessor directive. GLSL supports an extended syntax for this directive:

#line line_number
#line line_number source_string_number

When provided with two arguments, the directive sets __LINE__ to line_number and __FILE__ to source_string_number. Both arguments must be integral expressions.

This capability is commonly used by asset pipelines, pre-compilers, and custom #include implementations. When a preprocessor dynamically injects header files or external code into a shader string, it can insert a #line [line] [file_id] directive before and after the injected content. This ensures that any compiler diagnostics report the custom file ID assigned to that header rather than the linear array index passed to the graphics driver.