Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The goto statement is an unconditional branching construct in C that immediately transfers execution control to a user-defined labeled statement within the same function. It alters the sequential flow of a program by forcing the instruction pointer to jump directly to the memory address associated with the target label.

Syntax

The implementation requires two components: the goto keyword followed by an identifier, and the target label followed by a colon.
goto target_label;

/* ... intermediate code ... */

target_label:
    statement;

Technical Mechanics and Constraints

Function Scope Limitation The goto statement and its corresponding label must reside within the same function. The C compiler resolves labels at the function level; therefore, cross-function jumps are strictly prohibited. Attempting to jump out of or into a different function will result in a compilation error. Label Namespace and Declaration Labels occupy a distinct namespace in C. A label can share an identifier with a variable, function, or struct/union tag without causing a naming collision. However, caution is required with macros. Because the C preprocessor performs text substitution during translation phases that occur before the compiler evaluates namespaces, a macro collision will replace the label identifier with the macro’s expansion. If the macro expands to another valid identifier (e.g., #define target new_target), the preprocessor simply renames both the goto target and the label, resulting in valid, compilable code. A syntax error only occurs if the macro expands to something that is not a valid identifier, such as a keyword or a numeric literal. Historically (from C89 through C17), a label was strictly required to precede a valid C statement. If a label was placed at the very end of a compound statement (block), it had to be followed by a null statement (;). The C23 standard introduced free-standing labels, allowing labels to directly precede declarations or be placed at the very end of a compound statement without requiring a trailing null statement.
void example_function() {
    int target = 5;      /* Variable in standard namespace */
    
    goto target;         /* Jumps to the label 'target' */
    
    target:              /* Label in label namespace */
        /* In C23+, no statement is required here. */
        /* Pre-C23 requires a null statement (;). */
}
Directional Branching The jump can be executed in either direction:
  • Forward Jump: The goto statement precedes the label, causing the compiler to skip the intermediate instructions.
  • Backward Jump: The label precedes the goto statement, forcing the execution flow to return to an earlier point in the function, effectively creating a loop.

Memory and Initialization Rules

Variable Initialization Bypass If a forward goto jumps over a standard variable declaration that includes an initialization, the variable is still allocated in memory because its lifetime (storage duration) begins upon entry into the block. However, the initialization expression is skipped. The variable’s scope (identifier visibility) begins immediately after its declarator. Consequently, if the jump target is located after the declaration, the variable is in scope but will contain indeterminate (garbage) data until explicitly assigned.
void bypass_example() {
    goto skip_init;

    int x = 10; /* Lifetime begins at block entry, but assignment (= 10) is skipped */

    skip_init:
    /* x is in scope here, but its value is indeterminate */
    x = 20;     /* Explicit assignment is required */
}
Variable Length Arrays (VLAs) Introduced in C99, jumping from outside the scope of a Variable Length Array (VLA) or a variably modified type to a label inside its scope is strictly illegal. The compiler must evaluate the size of a VLA at runtime when its declaration is encountered; bypassing this evaluation via goto violates the language standard and triggers a compilation error. Conversely, jumping completely over a nested block that contains a VLA declaration is perfectly legal because the jump target resides outside the VLA’s scope. Block Entry A goto statement can jump into a nested compound statement (block). When this occurs, any local variables declared in that nested block begin their lifetime. However, their initialization expressions are only bypassed if the jump target (the label) is positioned after the declarations. If the label precedes the declarations, the initializations will execute normally.
Master C with Deep Grasping Methodology!Learn More