GLSL Switch Statement Default Label Placement Rules

The placement of the default label in an OpenGL Shading Language (GLSL) switch statement is governed by strict syntactic and structural rules defined in the official specification. While the default label offers flexibility regarding its relative position among case labels, it is constrained by scope limitations, uniqueness requirements, and strict control-flow semantics that differ notably from traditional C and C++ environments.

Relative Ordering

The default label is not required to appear at the end of the switch block. It can be placed at the very beginning, in between standard case labels, or at the end. Regardless of its position in the source code, the shader compiler will only evaluate the default branch if no case value matches the evaluated switch condition.

Uniqueness

A single switch statement can contain at most one default label. Declaring more than one default label within the same switch block results in a compilation error.

Prohibition Inside Nested Blocks

Unlike standard C/C++, GLSL strictly forbids labels from being placed inside nested compound statements or control-flow blocks within the switch body. A default label must reside directly within the root scope of the switch block. It cannot be nested inside:

  • An inner set of braces ({ ... })
  • A conditional block (if or else)
  • A loop construct (for, while, or do-while)

Because of this restriction, advanced C-style branching patterns such as Duff's device are invalid in GLSL.

Placement Relative to Executable Code

No executable statements are permitted before the first label in a switch body. If the default label is the very first label in the switch statement, it must appear before any executable shader logic. Any code placed before the initial case or default label is unreachable and will trigger a compile-time error.

Fallthrough Considerations

When the default label is placed anywhere other than the very end of the switch block, it is subject to standard fallthrough behavior. If execution enters the default block and does not encounter a break, return, or discard statement, execution will continue sequentially into the subsequent case label's instructions.