You can use any previously declared variable as an initialiser of another variable.
In this case as soon as the compiler parses int i it adds that to the symbol table, so when it sees the = i initialiser, the symbol can be resolved from the preceding declaration.
It is not an error because the compiler can make sense of it in that it can generate code that unambiguously does exactly what the source code specifies, seven if it is semantically suspect. The philosophy of C and C++ is to compile anything that can possibly be compiled syntactically. Semantic errors generally issue only warnings, and only then if such warnings are enabled.