3

I would like to write a for loop like this:

for (uint256 i = 0; i < length; unchecked { i += 1 }) {
    // ...
}

But unfortunately this does not compile (fails with an error "expected primary expression").

How can I write an unchecked for loop? That is, I would like to use unchecked arithmetic only to increment the index i - not for any other operation in the body of the loop.

Paul Razvan Berg
  • 17,902
  • 6
  • 73
  • 143

2 Answers2

7

You can do this by putting the post-iteration increment operation at the end of the loop:

for (uint256 i = 0; i < length;) {
    // ...
    unchecked { i += 1; }
}

Note though that this is safe to do only if you know that the post-iteration operation will never overflow the variable type of length.

Paul Razvan Berg
  • 17,902
  • 6
  • 73
  • 143
1

There's now a nicer way to do this in Solidity v0.8.19, thanks to the addition of user-defined operators.

I wrote a value type UC that makes unchecked for loops more concise and more readable:

// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.19;

import { UC, uc } from "unchecked-counter/UC.sol";

function iterate(uint256[] memory arr) pure { uint256 length = arr.length; for (UC i = uc(0); i < uc(length); i = i + uc(1)) { uint256 element = arr[i.into()]; } }

See the GitHub repo for more details:

Paul Razvan Berg
  • 17,902
  • 6
  • 73
  • 143