strtoul () vs. errno

I

Ivan Shmakov

[Cross-posting to for strtoul () is part of
ISO C.]
Incorrect. There are a number of POSIX defined calls where you
_must_ clear errno prior to the call in order to detect that an error
occurred during the call (strtoul, for example).

Curiously enough, I've always tested for failure with
(*endptr == str) after the call. To my mind, it aligns better
with the calling conventions of other functions, where one
checks the return value for failure first, and checks errno for
the cause if necessary afterwards.

--cut: http://pubs.opengroup.org/onlinepubs/9699919799/functions/strtoul.html --
If the subject sequence is empty or does not have the expected form,
no conversion shall be performed; the value of str shall be stored
in the object pointed to by endptr, provided that endptr is not a
null pointer.
--cut: http://pubs.opengroup.org/onlinepubs/9699919799/functions/strtoul.html --
 
M

Måns Rullgård

Ivan Shmakov said:
[Cross-posting to for strtoul () is part of
ISO C.]
Incorrect. There are a number of POSIX defined calls where you
_must_ clear errno prior to the call in order to detect that an error
occurred during the call (strtoul, for example).

Curiously enough, I've always tested for failure with
(*endptr == str) after the call. To my mind, it aligns better
with the calling conventions of other functions, where one
checks the return value for failure first, and checks errno for
the cause if necessary afterwards.

--cut: http://pubs.opengroup.org/onlinepubs/9699919799/functions/strtoul.html --
If the subject sequence is empty or does not have the expected form,
no conversion shall be performed; the value of str shall be stored
in the object pointed to by endptr, provided that endptr is not a
null pointer.
--cut: http://pubs.opengroup.org/onlinepubs/9699919799/functions/strtoul.html --

That misses the ERANGE case.
 
J

James Kuyper

[Cross-posting to for strtoul () is part of
ISO C.]

The C standard says nothing of the kind. In fact, footnote 122 in
n1570.pdf says: "Thus, a program that uses errno for error checking
should set it to zero before a library function call," The standard
library functions are restricted to setting errno to positive values,
precisely so that negative values may be used by any user code to
indicate additional error conditions.
Curiously enough, I've always tested for failure with
(*endptr == str) after the call. To my mind, it aligns better
with the calling conventions of other functions, where one
checks the return value for failure first, and checks errno for
the cause if necessary afterwards.

--cut: http://pubs.opengroup.org/onlinepubs/9699919799/functions/strtoul.html --
If the subject sequence is empty or does not have the expected form,
no conversion shall be performed; the value of str shall be stored
in the object pointed to by endptr, provided that endptr is not a
null pointer.
--cut: http://pubs.opengroup.org/onlinepubs/9699919799/functions/strtoul.html --

However, note that those are not the only possible error conditions.
Even if the subject sequence is not empty, and does have the expected
form, "If the correct value is outside the range of representable
values, ... ULONG_MAX ... is returned ... and the value of the macro
ERANGE is stored in errno." (C2011 7.22.1.4p8).
 
B

Bill Cunningham

Scott said:
Ivan Shmakov said:
Bill Cunningham <[email protected]> wrote:

[Cross-posting to for strtoul () is part of
ISO C.]
errno = 0;
You shouldn't set errno yourself. The behaviour is undefined.
Incorrect. There are a number of POSIX defined calls where you
_must_ clear errno prior to the call in order to detect that an
error occurred during the call (strtoul, for example).

Curiously enough, I've always tested for failure with
(*endptr == str) after the call. To my mind, it aligns better
with the calling conventions of other functions, where one
checks the return value for failure first, and checks errno for
the cause if necessary afterwards.

I also use code similar to:

bus = strtoull(argv[2], &cp, 0);
if ((cp == argv[2])
|| (*cp != '\0')
|| (bus > c_pcie_ecam::NUM_BUSES)) {
lp->log("Bus number must be less than %zu\n",
c_pcie_ecam::NUM_BUSES);

Is that :: above C++'s scoping operator?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
473,734
Messages
2,569,441
Members
44,832
Latest member
GlennSmall

Latest Threads

Top