Re: Implementation errors in strtol()

From: Joerg Wunsch <j_at_uriah.heep.sax.de>
Date: Sat, 22 Jan 2005 12:30:15 +0100
As Andrey Chernov wrote:

> > Do whatever you want, I think it's silly and should rather be
> > dropped as it is a useless feature, which could only lead people
> > to write unportable code.

> The code which _not_ expect this feature present is _equally_
> unportable.

Nope.  Just think about it: code which doesn't take this feature into
account needs to check for conversion errors by means of verifying
endptr.  It simply wouldn't care about errno at all, except for
possibly checking for overflows -- which only needs to be verified
after it is already clear from checking endptr that the conversion was
OK.  Thus, errno could not possibly be EINVAL anymore in that case.

Consequently, implementing EINVAL might cause an innocent programmer
to rely on it for finding conversion errors, as opposed to properly
checking endptr instead.  Thus it has the negative impact that it
might cause people to rely on non-portable features of a particular
implementation, the more in that the FreeBSD man page (unlike systems
like Solaris or Linux that simply quote the SUSP man page) explicitly
states that EINVAL is returned for conversion errors, without
mentioning that this feature is not portable as it employs a ``may''
clause from SUSP.

Thus we should at least document in the man page that EINVAL for
conversion errors is a FreeBSD extension that is allowable by the SUSP
but not guaranteed, and thus cannot be relied on.  I still think that
Posix/SUSP is bogus in that respect, but that probably applies to any
usage of `may' in a standard.

> I repeat: portable application must always consider _both_ cases
> since both are mentioned in the standard as possible ones.

Nope, properly checking endptr is sufficient to detect conversion
errors, so a portable application simply doesn't need to care for
errno in that case.

> BTW, where was you when this change was discussed and commited by
> first time long ago?

I probably wasn't much interested in it by that time.  See the
introduction in my first article in this thread, the problem only
became apparent to me now that I have to verify another strtol()
implementation for a completely different system.

> At those time I don't remember any "against" votes.

Well, Bruce wrote me that he was opposed to it even by that time.

As David Schultz wrote:

> Regarding the interpretation of sequences such as "0x" and "+":
> These are disallowed by the BNF in section 6.4.4.1 of the C99
> standard.

Ah, that's the trick I've been missing.  Thanks for explaining this.

> 7.20.1.4.7
>   If the subject sequence is empty or does not have the expected
>   form, no conversion is performed; ...

It rather confused me that this special case is explicitly mentioned
as a ``no conversion'' case, while anything else has to rely on
implied statements.

> Regarding the use of errno:
> The ISO C standard allows any library function to set errno to
> EFOO unless it explicitly says EFOO is used to mean something else
> for that function.  ...

Do you have a quote for that?

I know that Posix/SUSP basically interprets it that way, but I think
the second sentence in paragraph 3 of 7.5 is ambiguous, as that I
would interpret it as an explicit statement that for any function
where the use of errno is documented as part of the [C] standard,
errno must not be set in another way than documented.  This would
prohibit setting errno to EINVAL for strtol(), as the possible errno
modifications are documented for strtol() (either undmodified, or set
to ERANGE).

Again, I didn't meant to change this in FreeBSD, I just wondered about
it.

-- 
cheers, J"org               .-.-.   --... ...--   -.. .  DL8DTL

http://www.sax.de/~joerg/                        NIC: JW11-RIPE
Never trust an operating system you don't have sources for. ;-)
Received on Sat Jan 22 2005 - 10:40:05 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:26 UTC