# ++ / -- (increment / decrement)

> Increment or decrement a numeric variable or property by one. In statement position (i++;) and as a for increment the pre- and post-forms are identical. Pre-form in an expression returns the new value; post-form used as a value (old-value semantics) is not supported yet.

<!-- id: function-increment-decrement · area: function · stability: stable · html: https://osysharp.com/reference/function/increment-decrement/ -->

## Summary        {#summary}
`++` and `--` increment or decrement a numeric **lvalue** (a variable or property) by one. In statement
position (`i++;`) and as a loop increment, the pre-form (`++i`) and post-form (`i++`) are identical. As an
expression value the pre-form returns the **new** value, exactly C#; the post-form's old-value semantics
are not supported yet (a pointed compile error, never a silent wrong answer).

## Signature      {#signature}
```osy syntax
++x    // pre-increment  — value is the new x
x++    // post-increment — statement/for only
--x    // pre-decrement
x--    // post-decrement — statement/for only
```

## Description    {#description}
- The operand must be a numeric lvalue — an `int`/`long`/`decimal`/`double` variable or property. A
  non-numeric operand (`s++` on a string) or a non-lvalue (`(a + b)++`) is a compile error.
- Lowered to `x = x ± 1` (the same desugar `+=` uses), so it inherits numeric widening and assignability:
  incrementing a `long`/`decimal`/`double` widens the `1` accordingly.
- **Statement position** (`i++;`) and the **`for` increment** discard the value, so pre- and post-form are
  identical and both exact.
- **Pre-form in an expression** (`var y = ++i;`) returns the new value — exact C#.
- **Post-form used as a value** (`var y = i++;`, `f(i++)`) returns the *old* value in C#, which needs a
  sequencing step the engine doesn't have yet — it's a pointed compile error: *"post-increment 'x++' used
  as a value returns the OLD value — not supported yet; use the pre-form '++x' or put the ++ on its own
  statement."*
- Decompile normalizes to the assignment form (`i = i + 1`), the same round-trip `+=` takes.

## Examples       {#examples}
```osy title="statement + loop + member" test app=increment-examples
entity Gauge { int Hits; }

int Mix() { int i = 0; i++; ++i; i--; return i; }   // 0 +1 +1 -1 = 1

int LoopSum() {
  int total = 0;
  int i = 0;
  while (i < 5) { total = total + i; i++; }          // sum 0..4 = 10
  return total;
}

int PreValue() { int i = 41; return ++i; }           // pre-form returns the new value = 42

int BumpHits() {
  var g = new Gauge { Hits = 10 };
  g.Hits++;                                           // property increment
  g.Hits++;
  return g.Hits;                                      // 12
}
```

## See also       {#see-also}
- [Numeric types & literal suffixes](https://osysharp.com/reference/function/numeric-literals/) — the numeric types `++`/`--` operate on
- [Typed locals](https://osysharp.com/reference/function/typed-locals/) — declaring the counter (`int i = 0;`)
