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 [[assume(expression)]] attribute, introduced in C++23, is a statement attribute that asserts a given boolean expression will always evaluate to true at the exact point of execution. It serves purely as an optimization hint used by the compiler during the optimization and code-generation phases, without generating any executable code to evaluate the expression at runtime.

Syntax

The attribute appertains to an empty statement (a null statement), typically represented by a standalone semicolon.
[[assume(expression)]];

Core Mechanics and Undefined Behavior

  • No Runtime Evaluation: The expression is never evaluated at runtime. The compiler does not emit machine code to test the condition.
  • Undefined Behavior (UB): The program exhibits Undefined Behavior if the hypothetical evaluation of the expression at the point where the attribute is reached would result in any of the following:
    1. The expression evaluates to false.
    2. The evaluation throws an exception.
    3. The expression itself contains undefined behavior.
  • Discarded Side Effects: Because the expression is never executed, any side effects within the expression (e.g., variable mutations, I/O operations, or state-altering function calls) do not occur at runtime.

Language Rules and Constraints

  1. Type Conversion: The expression must be contextually convertible to bool.
  2. Potentially-Evaluated Expression: Even though it is not evaluated at runtime, the expression is a potentially-evaluated expression (unlike the operands of decltype or sizeof). Consequently, entities referenced within the expression are ODR-used. The compiler requires definitions for these entities and will trigger template instantiations based on their appearance, which is necessary so the optimizer can inspect their definitions.
  3. Scope and Name Resolution: Names and variables used within the expression are resolved exactly as if the expression were a standard evaluated statement at that specific point in the lexical scope.
  4. Coroutine Restrictions: Await-expressions (co_await) and yield-expressions (co_yield) are explicitly prohibited by the C++ standard from appearing within the [[assume]] expression.
Despite the lack of runtime evaluation, complex logic including standard control flow statements (return, break, continue, or goto) is permitted if encapsulated within a lambda expression defined inside the [[assume]] expression.
// Valid: Lambda containing standard control flow statements
[[assume([]{ 
    for (int i = 0; i < 5; ++i) { 
        if (i == 3) break; 
    } 
    return true; 
}())]];

Structural Placement

Because [[assume]] appertains to an empty statement, it can be placed anywhere an empty statement is syntactically valid. It is bound to the control flow of the program.
void process(int* ptr, int size) {
    // Valid placement: appertains to a standalone empty statement
    [[assume(ptr != nullptr)]];
    
    // Valid placement: inside control flow
    if (size % 2 == 0) {
        [[assume(size >= 2)]];
    }
}

Distinction from assert

Mechanically, [[assume(expr)]] differs fundamentally from the standard <cassert> macro assert(expr):
  • assert(expr) evaluates the expression at runtime (in debug builds) and terminates the program if the result is false.
  • [[assume(expr)]] is not evaluated at runtime. It relies entirely on the compiler’s optimization phase, discarding all side effects, and results in Undefined Behavior if the hypothetical evaluation would have been false, thrown an exception, or triggered UB itself.
Master C++ with Deep Grasping Methodology!Learn More