The goto
jump itself is fine. By [stmt.dcl]/3:
It is possible to transfer into a block, but not in a way that bypasses declarations with initialization. A program that jumps from a point where a variable with automatic storage duration is not in scope to a point where it is in scope is ill-formed unless the variable has scalar type [...] and is declared without an initializer (8.5).
However, what is not legal is to read an uninitialized variable by [dcl.init], and thus your program has undefined behaviour at runtime if you call f
with an argument less than 10.