Tilde is the one's complement operator. I would not think of that as
bulletproof code, the results might well be different on a one's complement
machine than they are on a two's complement machine. The result is
"negative zero" on a one's complement machine.
Given the presence of the shift operator, I would have thought that it
is more important to the author that i has the all ones bit pattern
that it represents any particular number. For this reason ~0 is
initially a more logical choice than -1.
We don't know what i is, but whether the loop will terminates if it is
signed is implementation defined. If the implementation uses a two's
complement representation and the shift operator for signed ints on
the implementation does an arithmetic right shift (shifts in the sign
bit and leaves the sign bit unchanged) then the loop will not
terminate.
For this reason, if this is to be portable code, i should be unsigned.
If i is unsigned then -1 and ~0 are both equivalent as both are
guaranteed to represent 2^N - 1.
OK, the last paragraph isn't true

. Technically -1 and ~0U are
guaranteed to represent 2^N - 1 where N is the number of value bits
in the representation of unsigned int.
OK, the last paragraph isn't true

. If i is wider than an int
(supposed it is an unsigned long) then ~0UL is required. In general,
the constant 0 needs to be widened to the correct width before the ~
operator is applied.