The case for a modern language
This isn&#x27;t the usual way this is coded:<p><pre><code>  char *one = &quot;one&quot;;
  char *end;
  errno = 0; &#x2F;&#x2F; remember errno?
  long i = strtol(one, &amp;end, 10);
  if (errno != 0) {
      perror(&quot;Error parsing integer from string: &quot;);
  } else if (i == 0 &amp;&amp; end == one) {
      fprintf(stderr, &quot;Error: invalid input: %s\n&quot;, one);
  } else if (i == 0 &amp;&amp; *end != &#x27;\0&#x27;) {
      f__kMeGently(with_a_chainsaw); 
  }
</code></pre>
It&#x27;s actually like this:<p><pre><code>  errno = 0;

  long i = strtol(input, &amp;end, 10);

  if (end == input) {
    &#x2F;&#x2F; no digits were found
  } else if (*end != 0 &amp;&amp; no_ignore_trailing_junk) {
    &#x2F;&#x2F; unwanted trailing junk
  } else if ((i == LONG_MIN || i == LONG_MAX)) &amp;&amp; errno != 0) {
    &#x2F;&#x2F; overflow case
  } else {
    &#x2F;&#x2F; good!
  }
</code></pre>
errno only needs to be checked in the LONG_MIN or LONG_MAX case. These cares are ambiguous: LONG_MIN and LONG_MAX are valid values of type long, and they are used for reporting an underflow or overflow. Therefore errno is reset to zero first. Otherwise what if errno contains a nonzero value, and LONG_MAX happens to be a valid, non-overflowing value out of the function?<p>Anyway, you cannot get away from handling these cases no matter how you implement integer scanning; they are inherent to the problem.<p>It&#x27;s not strtol&#x27;s fault that the string could be empty, or that it could have a valid number followed by junk.<p>Overflows stem from the use of a fixed-width integer. But even if you use bignums, and parse them from a stream (e.g. network), you may need to set a cutoff: what if a malicious user feeds you an endless stream of digits?<p>The bit with errno is a bit silly; given that the function&#x27;s has enough parameters that it could have been dispensed with. We could write a function which is invoked exactly like strtoul, but which, in the overflow case, sets the *end pointer to NULL:<p><pre><code>  &#x2F;&#x2F; no assignment to errno before strtol

  int i = my_strtoul(input, &amp;end, 10);

  if (end == 0) {
    &#x2F;&#x2F; underflow or overflow, indicated by LONG_MIN or LONG_MAX value
  } else if (end == input) {
    &#x2F;&#x2F; no digits were found
  } else if (*end != 0 &amp;&amp; no_ignore_trailing_junk) {
    &#x2F;&#x2F; unwanted trailing junk, but i is good
  } else {
    &#x2F;&#x2F; no trailing junk, value in i
  }
</code></pre>
errno is a pig; under multiple threads, it has to access a thread local value. E.g<p><pre><code>  #define errno (*__thread_specific_errno_location())
</code></pre>
The designer of strtoul didn&#x27;t do this likely because of the overriding requirement that the <i>end</i> pointer is advanced past whatever the function was able to recognize as a number, no matter what. This is lets the programmer write a tokenizer which can diagnose the overflow error, and then keep going with the next token.