64-Bit Integer Literal Suffixes in GLSL

This article explains how to define 64-bit integer constants in the OpenGL Shading Language (GLSL) using the l and ul literal suffixes. It covers the required language extensions, the exact syntax rules for signed and unsigned 64-bit literals in various number bases, and practical code examples for shader development.


Prerequisites

Standard GLSL natively defaults integer literals without suffixes to 32-bit signed integers (int). To use 64-bit integer types and their literal suffixes, you must enable the 64-bit integer extension in your shader:

#version 450
#extension GL_ARB_gpu_shader_int64 : require

This extension introduces the int64_t and uint64_t scalar types, along with their corresponding vector types and literal suffix support.


Signed 64-Bit Integer Literal Syntax (l / L)

To explicitly define a signed 64-bit integer constant (int64_t), append the letter l or L to an integer literal. The suffix is case-insensitive, though using uppercase L is widely recommended to avoid visual confusion with the digit 1.

  • Suffix: l or L
  • Target Type: int64_t

Examples

// Decimal
int64_t a = 5000000000L;
int64_t b = -42L;

// Hexadecimal
int64_t c = 0x7FFFFFFFFFFFFFFFL;

// Octal
int64_t d = 077777777777L;

Unsigned 64-Bit Integer Literal Syntax (ul / UL)

To declare an unsigned 64-bit integer constant (uint64_t), combine the unsigned indicator (u or U) with the 64-bit length indicator (l or L). GLSL allows these characters in either order and in any combination of case.

  • Valid Suffixes: ul, uL, Ul, UL, lu, Lu, lU, LU
  • Target Type: uint64_t

Examples

// Decimal
uint64_t x = 10000000000UL;
uint64_t y = 500ul;

// Hexadecimal
uint64_t max_val = 0xFFFFFFFFFFFFFFFFUL;

// Reversed suffix order (valid in GLSL)
uint64_t z = 123456789LU;

Key Syntax Rules and Behaviors

  1. Avoid Suffix Omission for Large Values: In GLSL, integer values exceeding the range of standard 32-bit integers will trigger a compilation error if not explicitly appended with an l or L suffix.
  2. Case Insensitivity: Both the unsigned marker (u/U) and the 64-bit marker (l/L) can be uppercase or lowercase, but standard practice favors UL or L for improved readability.
  3. No Separator Characters: Unlike modern C++ or GLSL extensions for floating-point literals, digits cannot be separated by apostrophes or underscores.