There are a number of coding standards which stipulate against mixing tests and variable declarations or increments in loops (both while and for). Most have good reasoning, with the main point being that for clarity the variables used inside the "for" loop should be limited to those which control the loop.
@jonnin's suggestion works along these lines by moving the declarations outside the loop.
Clearly, by the OP's test clause, either a limit of 5 or a nullptr in the list terminates the loop. Compliant with the coding standards I mention, one or the other should suffice, where alternative tests are often placed inside the code block the loop controls (using break, usually).
That said, there's an "out" here.
If one fashions an end pointer related to "pa", the use of "i" is obviated, like this:
1 2 3 4
|
char **p_end = (char **)pa; // not sure why this must be cast, but I echo that blindly
for( char **list = (char **) pa; *list && list < p_end; ++list ).....
|
If one considers "list" to be an iterator, this is in line with iterator usage elsewhere.