Skip to content

Instantly share code, notes, and snippets.

@0xxfu
Created June 15, 2023 15:21
Show Gist options
  • Save 0xxfu/67eb8e3d8fe0b8d35370c1263e606d38 to your computer and use it in GitHub Desktop.
Save 0xxfu/67eb8e3d8fe0b8d35370c1263e606d38 to your computer and use it in GitHub Desktop.

The increment in for loop post condition can be made unchecked

Consider the following generic for loop:

for (uint i = 0; i < length; i++) {
    // do something that doesn't change the value of i
}

In this example, the for loop post condition, i.e., i++ involves checked arithmetic, which is not required. This is because the value of i is always strictly less than length <= 2**256 - 1. Therefore, the theoretical maximum value of i to enter the for-loop body is 2**256 - 2. This means that the i++ in the for loop can never overflow. Regardless, the overflow checks are performed by the compiler.

Unfortunately, the Solidity optimizer is not smart enough to detect this and remove the checks. One can manually do this by:

for (uint i = 0; i < length; i = unchecked_inc(i)) {
    // do something that doesn't change the value of i
}

function unchecked_inc(uint i) returns (uint) {
    unchecked {
        return i + 1;
    }
}

Note that it’s important that the call to unchecked_inc is inlined. This is only possible for solidity versions starting from 0.8.2.

Gas savings: roughly speaking this can save 30-40 gas per loop iteration. For lengthy loops, this can be significant!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment