In the loop, you have the current integer value, determined by the first digits. You are going to do:
curval = curval * 10 + digit; // digit converted from '0'..'9' to 0..9 already
You can test overflow with:
if (curval > UINT32_MAX / 10 || (curval == UINT32_MAX / 10 && digit > UINT32_MAX % 10)) ...overflow would occur... else curval = curval * 10 + digit;
Division and module operations are compile-time operations, not run-time operations.
One of the advantages of this approach in using more than 32-bit unsigned integer for calculation is that it can be extended to work with large integers - with 64-bit integers and uintmax_t integers - by changing the constant from UINT32_MAX to UINT64_MAX or UINTMAX_MAX. This is all that is needed (except for changing the types of variables, of course).
The same basic test also works for signed types, but there is an additional complication. It is easier to use 16-bit integers for demonstration purposes (fewer digits to print and think), so I will move on to the 16-bit 2'-complement short with:
USHRT_MAX = 65535SHRT_MAX = 32767SHRT_MIN = -32768
The problem is that the short type can store -32768, but the largest positive value you can copy is 32767. For all values except SHRT_MIN, the test above will work fine. There are ways around this dilemma. One of them is to keep curval as a negative value during the calculation and cancel it before returning if it should be positive. Then your testing could be:
if (curval < SHRT_MIN / 10 || (curval == SHRT_MIN / 10 && digit > -(USHRT_MIN / 10)) ...overflow would occur... else curval = curval * 10 - digit; // Note subtraction!
You still need to check that curval not SHRT_MIN before negating a negative value. (Theoretically, you should verify that -SHRT_MAX != SHRT_MIN allow systems other than two binary additions, the values specified for the limits satisfy this condition.)
The same thinking and methods apply to INT_MAX , INT32_MAX , INT64_MAX and INTMAX_MAX , of course.