Date: Sun, 27 Jan 2002 07:44:20 +1100 (EST) From: Bruce Evans <bde@zeta.org.au> To: Chad David <davidc@acns.ab.ca> Cc: <arch@FreeBSD.ORG> Subject: Re: strtod() Message-ID: <20020127070622.K35323-100000@gamplex.bde.org> In-Reply-To: <20020124135250.A454@colnta.acns.ab.ca>
next in thread | previous in thread | raw e-mail | index | archive | help
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 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: %%% 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(). Bruce 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?20020127070622.K35323-100000>