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.