In the loop, only the image pointer is used and the C compiler
has no reason to keep the image_smob value anywhere. If
scm_cons results in a garbage collection, image_smob might
not be on the stack or anywhere else and could be freed, leaving the
loop accessing freed data. The use of scm_remember_upto_here_1
prevents this, by creating a reference to image_smob after all
data accesses.

There’s no need to do the same for lst, since that’s the return
value and the compiler will certainly keep it in a register or
somewhere throughout the routine.

The clear_image example previously shown (see Type checking)
also used scm_remember_upto_here_1 for this reason.

It’s only in quite rare circumstances that a missing
scm_remember_upto_here_1 will bite, but when it happens the
consequences are serious. Fortunately the rule is simple: whenever
calling a Guile library function or doing something that might, ensure
that the SCM of a smob is referenced past all accesses to its
insides. Do this by adding an scm_remember_upto_here_1 if
there are no other references.

In a multi-threaded program, the rule is the same. As far as a given
thread is concerned, a garbage collection still only occurs within a
Guile library function, not at an arbitrary time. (Guile waits for all
threads to reach one of its library functions, and holds them there
while the collector runs.)