And how does this avoid returning nonsense if the number is too large? (Wrapping if the accumulator is unsigned, straight to UB land if signed.) Not reporting overflows as errors is one of the major problems demonstrated by TFA.
you could check if ret > ret * 10 + characters[i]-48, if so it has wrapped around and you return an error
you could check if ret > ret * 10 + characters[i]-48, if so it has wrapped around and you return an error