bug-gnulib
[Top][All Lists]
Advanced

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

Re: source(builtin) and read(2)


From: Paul Eggert
Subject: Re: source(builtin) and read(2)
Date: Fri, 30 Mar 2007 14:34:09 -0700
User-agent: Gnus/5.1008 (Gnus v5.10.8) Emacs/21.4 (gnu/linux)

Geoff Clare writes:

> If the following code:
>
>    ssize_t var;
>    var = SSIZE_MAX;
>    ++var;
>    if (var > SSIZE_MAX)
>       puts("SSIZE_MAX wrong");
>
> outputs "SSIZE_MAX wrong" on any implementation, then var is an object
> of type ssize_t which was able to contain a value greater than
> SSIZE_MAX, and therefore the implementation's definition of SSIZE_MAX
> does not conform to the standard.

That's not the case, and this indicates how murky the waters are in
this area.  In C, that "++var" has undefined behavior, and a
conforming implementation can therefore do anything it likes with this
example, which means it can indeed print "SSIZE_MAX wrong".


> The ssize_t type was introduced (in 1990) in order to allow read()
> and write() to read and write more than INT_MAX bytes.  This is clear
> from the rationale for read():

   "The use of I/O with large byte counts has always presented
    problems. Ideas such as lread() and lwrite() (using and returning
    longs) were considered at one time. The current solution is to
    use abstract types on the ISO C standard function to read() and
    write(). The abstract types can be declared so that existing
    functions work, but can also be declared so that larger types can
    be represented in future implementations.

But that rationale can be interpreted a different way.  Suppose it's
1990 and we have a new machine with 32-bit int and 64-bit size_t, with
a traditional 'read' that returns 'int' so its result is limited to 32
bits.  We define ssize_t to be 64 bits because we want to fix this
while we adjust our machine to conform to POSIX (this doesn't break
the API since 'int' is the lower half of a 64-bit register), but in
the meantime we're stuck with a large body of code that uses 'int' and
assumes a 32 bit maximum.  On this implementation ssize_t would be 64
bits wide, but SSIZE_MAX would be 2**31 - 1.

This is my understanding of why
<http://www.opengroup.org/susv3/basedefs/sys/types.h.html> says "The
type ssize_t shall be capable of storing values at least in the range
[-1, {SSIZE_MAX}]" which has the clear implication that ssize_t might
be able to store values greater than SSIZE_MAX, just as it it might be
able to store values less than -1.

Perhaps we should remove this backward-compatibility hack, but I think
it should be done as a conscious change to the standard, not merely as
a reinterpretation of existing wording.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]