Protecting the world

from criminally bad code

atol

Synopsis

#include <stdlib.h>

long atol(const char* s);

Description

The atol function converts a null-terminated string to a long integer.

Pitfalls

Undefined behaviour on overflow

The behaviour of atol is undefined if the string has a value outside of the range that can be represented by a long[1]. It follows that atol is not safe to use unless it can be shown that (by circumstance or design) such an overflow will not happen.

One way to be ensure this would be to check that the input is no more than nine characters in length. The maximum possible value is then 999,999,999, which is within the range that any implementation of ISO C must be able to represent as an long[2].

For longer inputs, the effort required to exclude the possibility of overflow is likely to outweigh any convenience gained from using atol.

Lack of validation

The atol function does not validate its input in any way:

  • Trailing non-numeric content is silently ignored[3].
  • Inputs that do not begin with a number (even after skipping whitespace) give a result of zero[4].

The effect is to convert the string into a long integer at any cost, even if it bears no resemblance to one. There are two problems with this behaviour:

  • Erroneous inputs are silently ignored.
  • Zero is assumed to be a suitable default value, which may or may not be appropriate.

These issues could be overcome by validating the input before calling atol, but as above the effort required to do this is likely to outweigh any convenience gained from using this function.

Alternatives

Using strtol

The function strtol can be used in a way that avoids the above pitfalls:

  • Overflow does not invoke undefined behaviour, and is reported by setting errno to the value ERANGE.
  • Erroneous inputs can be detected by checking that at least one character has been converted, and that the last such character is a digit.
  • If required, it is possible to determine whether all of the input was converted by checking whether the next character is null.

Portability

  •  C90
  •  C99
  •  C++98
  •  C++11

In C++, use of the header <stdlib.h> is deprecated in favour of <cstdlib>.

Recommendation

Use of atol should be viewed with suspicion as it is rarely justified.

Notes

  • [1] C99 §7.20.1 ¶1
  • [2] C99 §5.2.4.2.1 ¶1 (requires that LONG_MAX be at least +2,147,483,647)
  • [3] C99 §7.20.1.4 ¶4
  • [4] C99 §7.20.1.4 ¶8

Further reading

  • The atoi, atol and atoll functions, Programming languages — C, ISO/IEC 9899:1999, §7.20.1.2, p306
  • atol, The Open Group Base Specifications, Issue 7, The Open Group, 2008
  • atol(3), Linux Programmer’s Manual, The Linux man-pages project
  • Parsing of Integers, The GNU C Library Reference Manual, The GNU Project