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 -- (decrement) operator is a unary operator that subtracts exactly one from the value of its operand. The operand must be a modifiable lvalue of an arithmetic type (integer or floating-point) or a pointer to a completely-defined object type. The operator exists in two distinct forms, which differ fundamentally in their evaluation semantics and value categories.

Prefix Decrement (--x)

The prefix form decrements the value of the operand and yields an lvalue identifying the modified object.
--operand;
Semantics:
  1. The value of operand is decreased by 1.
  2. The expression evaluates to the updated operand as an lvalue.
  3. Because it yields an lvalue, the result of a prefix decrement can be chained or assigned to. However, for fundamental types, chaining operations like --(--x) prior to C++11 results in strictly Undefined Behavior due to modifying a scalar variable twice without an intervening sequence point.

Postfix Decrement (x--)

The postfix form decrements the value of the operand but yields a prvalue (pure rvalue) representing the value of the object before the modification occurred.
operand--;
Semantics:
  1. A temporary copy of operand’s current value is created.
  2. The value of the actual operand is decreased by 1.
  3. The expression evaluates to the temporary copy (the original value) as a prvalue.
  4. For fundamental types, because the result is a prvalue of a non-class type, it cannot be assigned to or chained (e.g., (x--)-- is a compilation error). However, for user-defined class types, a prvalue can invoke non-const member functions. Therefore, (obj--)-- will successfully compile for a class type unless its postfix operator is explicitly lvalue-reference qualified.

Type-Specific Mechanics

  • Arithmetic Types: For integers and floating-point numbers, the operator performs standard subtraction of 1 or 1.0.
  • Pointer Types: When applied to a pointer, the decrement operation is scaled by the size of the type the pointer addresses. It subtracts sizeof(T) bytes from the memory address, moving the pointer backward by exactly one element of type T.
  • Boolean Types: The -- operator is strictly ill-formed when applied to operands of type bool.

Operator Overloading

When defining the -- operator for user-defined types, C++ requires distinct function signatures to differentiate between prefix and postfix resolution. The postfix version utilizes a dummy int parameter exclusively for overload resolution.
class CustomType {
    int data;
public:
    // Prefix decrement: Returns an lvalue reference, yielding an lvalue
    CustomType& operator--() {
        this->data -= 1;
        return *this;
    }

    // Postfix decrement: Returns a value type, yielding a prvalue
    // Note: Can be lvalue-reference qualified (e.g., operator--(int) &) to prevent (obj--)--
    CustomType operator--(int) {
        CustomType temp = *this; // Copy state
        this->data -= 1;         // Mutate original
        return temp;             // Return unmodified copy
    }
};

Evaluation Overhead

For fundamental types, compilers trivially optimize both forms to identical machine code if the return value is discarded. However, for user-defined types, the postfix decrement inherently requires allocating a temporary object and invoking a copy constructor. Consequently, the prefix form (--x) is computationally cheaper and is the standard convention unless the pre-decremented state is explicitly required by the surrounding expression.
Master C++ with Deep Grasping Methodology!Learn More