From owner-freebsd-arch Sat Jan 26 13:27:49 2002 Delivered-To: freebsd-arch@freebsd.org Received: from mail.acns.ab.ca (mail.acns.ab.ca [142.179.151.95]) by hub.freebsd.org (Postfix) with ESMTP id 3AFED37B416 for ; Sat, 26 Jan 2002 13:27:44 -0800 (PST) Received: from colnta.acns.ab.ca (colnta.acns.ab.ca [192.168.1.2]) by mail.acns.ab.ca (8.11.6/8.11.3) with ESMTP id g0QLRZV11417; Sat, 26 Jan 2002 14:27:35 -0700 (MST) (envelope-from davidc@colnta.acns.ab.ca) Received: (from davidc@localhost) by colnta.acns.ab.ca (8.11.6/8.11.3) id g0QLRZi07288; Sat, 26 Jan 2002 14:27:35 -0700 (MST) (envelope-from davidc) Date: Sat, 26 Jan 2002 14:27:34 -0700 From: Chad David To: Bruce Evans Cc: Chad David , arch@FreeBSD.ORG Subject: Re: strtod() Message-ID: <20020126142734.A7139@colnta.acns.ab.ca> Mail-Followup-To: Bruce Evans , Chad David , arch@FreeBSD.ORG References: <20020124135250.A454@colnta.acns.ab.ca> <20020127070622.K35323-100000@gamplex.bde.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: <20020127070622.K35323-100000@gamplex.bde.org>; from bde@zeta.org.au on Sun, Jan 27, 2002 at 07:44:20AM +1100 Sender: owner-freebsd-arch@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG 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