tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: strtonum(3) from OpenBSD?



At Fri, 3 Jul 2009 21:25:10 +0000, David Holland 
<dholland-tech%netbsd.org@localhost> wrote:
Subject: Re: strtonum(3) from OpenBSD?
> 
> On Thu, Jul 02, 2009 at 12:21:40PM -0400, Greg A. Woods wrote:
>  > > These are not equivalent if errno might contain a trap representation
>  > > for non-LONG_MAX returns.  (Because of strtol()'s special case for
>  > > errno, this can happen only if it was that way on entry.)
>  > 
>  > What exactly do you mean by "trap representation" in this context --
>  > that's not normal terminology I'm aware of for the _C_ Programming
>  > Language.  It's certainly not something that applies to ISO C89 or ISO
>  > C90 so far as I can find.
> 
> Try the C standard, also known as "C99".

Yes, I'm aware of ISO C99, and I'm aware of the possibility it gives for
an implementation defined feature to support invalid values for certain
types, which they refer to as "trap representations".  (I now do
understand a trap representation can trigger a trap exception on any
type of access, at least for non-auto variables that is.)

However as I say above, the code in question, the compilers used, and
the particular APIs we're discussing, are not yet fully conforming to
ISO C99, no matter how much anyone might desire them to be.  Even if you
take partial C99 compatibility as sufficient for this discussion, we're
still left without any compilation environment for NetBSD which supports
"trap representations" for integer values (GCC Manual, Section 4.5).

Also, to be overly pedantic, IIUC errno cannot actually contain a trap
representation after it has been set explicitly to a valid value, and
indeed that happens, according to the standard, at program start-up
time, so even if the programmer forgets to reset it to zero before
calling strtol() there's still no danger that it will contain a trap
representation after calling strtol().  More on this a bit later.

To be even more pedantic, it still really doesn't matter whether errno
contains a trap representation or not -- it's not going to change the
ultimate outcome since either one must ensure both conditions hold
simultaneously, or one must only check errno.  Either way errno must be
accessed so in the end it still doesn't matter which test one does
first.  The program might blow up, the terms of the expression still
commute.

Also no POSIX-compatible implementation I'm aware of, and no current
NetBSD-hosted C implementation I'm aware of, supports any trap
representation values for any type that may (as far as I understand)
validly be used to represent errno ("errno is implemented as a macro
which expands to a modifiable lvalue of type int", and all the C
compilers I know of for NetBSD, or any POSIX system for that matter, are
two's-complement implementations with no reserved bits in any of their
integer types).

Finally to paraphrase and summarise a discussion that took place on
comp.std.c last year, ISO C99 says errno starts with the value zero
(i.e. it is most certainly not starting with a value which is a trap
representation) and allows (or as we've seen sometimes even requires)
library functions to assign other values to errno.  ISO C99 also says
that assigning a "value" cannot ever produce a trap representation.
Therefore even on platforms with "int" values that can be trap
representations, during normal execution errno cannot ever come to
contain a trap representation.

I do also see now, IIUC, that C99 implementations may set errno=ERANGE
when integer arithmetic triggers an overflow, though I've yet to hear
tell of one which actually does this.  This feature seems to be even
more rare than one's-complement implementations, especially in the real
world of actual C implementations claiming ISO c99 compatibility.  From
my examination of a variety of strotol() implementations (admittedly all
coded using C90 at newest), all the ones I've seen do overflow
prediction and would not trigger any arithmetic overflow during normal
execution anyway.  In any case, nothing I can find anywhere suggests
that any normal valid operation can ever cause the value of errno to
suddenly contain a trap representation (on platforms which do have trap
representations for "int" values, that is).  I suppose one could
envision a scenario where a wild pointer writes garbage into the storage
referenced by errno and that said garbage could, on some C
implementations, be equivalent to a trap representation for an "int"
value.  But that would be a bug where something had gone drastically
wrong in the execution environment, and in that case it still wouldn't
really matter if accessing errno caused a trap because the environment
was already hosed anyway and the sooner something blows up, the better.

-- 
                                                Greg A. Woods
                                                Planix, Inc.

<woods%planix.com@localhost>       +1 416 218-0099        http://www.planix.com/

Attachment: pgpahCH9cyZCU.pgp
Description: PGP signature



Home | Main Index | Thread Index | Old Index