Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 26 Jan 2002 14:27:34 -0700
From:      Chad David <davidc@acns.ab.ca>
To:        Bruce Evans <bde@zeta.org.au>
Cc:        Chad David <davidc@acns.ab.ca>, arch@FreeBSD.ORG
Subject:   Re: strtod()
Message-ID:  <20020126142734.A7139@colnta.acns.ab.ca>
In-Reply-To: <20020127070622.K35323-100000@gamplex.bde.org>; from bde@zeta.org.au on Sun, Jan 27, 2002 at 07:44:20AM %2B1100
References:  <20020124135250.A454@colnta.acns.ab.ca> <20020127070622.K35323-100000@gamplex.bde.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, Jan 27, 2002 at 07:44:20AM +1100, Bruce Evans wrote:
> On Thu, 24 Jan 2002, Chad David wrote:
> 
> > On current (as of today) strtod() sets errno to EINVAL even when no error
> > actually occurs.  While I understand that the value of errno is undefined
> > if an error does not occur, there is confusion when 0.0 is passed and the
> > conversion is successful.
> > ...
> > I'm not saying that just because Solaris chooses to implement the
> > interface in this way that FreeBSD should, but I do think that there is a
> > lot of room for introducing (needless) complexity when porting
> > applications from Solaris (like I am), and that while FreeBSD does not
> > have to set EINVAL when an error occurs, it should NOT set it when an
> > error does not occur.
> >
> > Note that on stable errno does not get set to EINVAL.
> 
> I think you mean strtol().  strtod() hasn't changed significantly since
> RELENG_4.  The integer strto*() functions now set it in the following

Depending on what you mean by "you mean strtol()"?  strtol() is being called
indirectly by strtod() via localeconv(), and it is failing (since around
1.3 or localeconv.c).

strtod() given 0.0 does not set errno == EINVAL on any platform I have
access to (FreeBSD stable, NetBSD, Solaris (8 and 9), Debian etc), only
current does this, and it is not allowed to do that.  It MAY set it if
there is an error, and to me this implies that it CANNOT set it when
there is no error.

> cases:
> (1) if the base is weird, even if there are no weird digits.  This is a
>     bug IMO.  All C standards seem to require that even negative bases
>     just work.
> (2) if no input is consumed.
> 
> I agree that errno shouldn't be set (by the strto* family at least)
> when there is no error.  I think standards don't permit it (they permit
> gratutiously clobbering errno, but not when the setting of errno is
> explicitly documented).  Setting it when no input is consumed is not
> very useful and has broken the the error handling of at least test(1)
> and dd(1) so far.  This case can be detected easily by checking the
> end pointer.  The breakage has been fixed in test(1).  Here it is in
> dd/args.c:

I agree with you 100%.  Checking errno when 0.0 is returned doesn't really
get you very far.  If you follow the standards, and errno == EINVAL then
you can assume an error occured, but if errno == 0 you do not know anything.
The only way to know for sure is to check endptr, so checking for EINVAL is
a waste of time.

> 
> %%%
> 	errno = 0;
> 	num = strtouq(val, &expr, 0);
> 	if (errno != 0)				/* Overflow or underflow. */
> 		err(1, "%s", oper);
> 
> 	if (expr == val)			/* No valid digits. */
> 		errx(1, "%s: illegal numeric value", oper);
> %%%
> 
> The "Overflow or underflow" comment has rotted in 3 steps:
> (1) It was changed from "Overflow" to "Overflow or underflow" when
>     strtuol() was changed to strtoq().  This was just an obfuscation.
>     "Underflow" must be read as "overflow towards negative infinity",
>     but it's less confusing to just say "overflow".
> (2) The code was wrong because strto*() may set errno, and broke when
>     strtoq() started setting it.  The "illegal numeric value" case
>     became unreachable.
> (3) "Overflow or underflow" wasn't changed back to "Overflow" when
>     strtoq() was changed to strtouq().

Code like this is what I'm dealing with.  My point is that if you set
errno == 0, and then after the function it is != 0, an error DID occur,
as long as the return value == 0.0 or HUGE_VAL I guess.

Am I making any sense?

-- 
Chad David        davidc@acns.ab.ca
www.FreeBSD.org   davidc@freebsd.org
ACNS Inc.         Calgary, Alberta Canada
Fourthly, The constant breeders, beside the gain of eight shillings
sterling per annum by the sale of their children, will be rid of the
charge of maintaining them after the first year. - Johnathan Swift

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020126142734.A7139>